Getting the error NoSuchMethodError: org.apache.cassandra.thrift.TBinaryProtocol when using Apache Cassandra,Kundera,Spring MVC

StackOverflow https://stackoverflow.com/questions/18638491

Question

I keep getting the message

 java.lang.NoSuchMethodError: org.apache.cassandra.thrift.TBinaryProtocol: method <init>(Lorg/apache/thrift/transport/TTransport;)V not found
 at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.initiateClient(CassandraSchemaManager.java:446)
at com.impetus.kundera.configure.schema.api.AbstractSchemaManager.exportSchema(AbstractSchemaManager.java:101)
at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.exportSchema(CassandraSchemaManager.java:138)
at com.impetus.kundera.configure.SchemaConfiguration.configure(SchemaConfiguration.java:172)
at com.impetus.kundera.configure.ClientMetadataBuilder.buildClientFactoryMetadata(ClientMetadataBuilder.java:45)
at com.impetus.kundera.persistence.EntityManagerFactoryImpl.configureClientFactories(EntityManagerFactoryImpl.java:352)
at com.impetus.kundera.persistence.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:116)
at com.impetus.kundera.KunderaPersistence.createEntityManagerFactory(KunderaPersistence.java:83)
at com.impetus.kundera.KunderaPersistence.createContainerEntityManagerFactory(KunderaPersistence.java:65)

Whenever I try to run my Java Spring MVC 3.2 Project. I am trying to connect to Apache Cassandra 1.2.8 that I have installed on my machine from the Spring WebApp using Kundera. I have included the following dependencies in the pom.xml file of the project:

  1. scale7-pelops(1.3-1.1.x)
  2. cassandra-all & cassandra-clientutil (1.2.8)
  3. kundera-core & kundera-cassandra (2.6)

My Spring Project uses XML-less configuration (Java Config) and JPA apart from kundera's persistence.xml which is under {PROJECT}/src/main/resources/META-INF so as to be at the base of the classpath during deployment. My persistence.xml looks like:

    <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0">
        <persistence-unit name="cassandra_pu">
            <provider>com.impetus.kundera.KunderaPersistence</provider> 
            <class>org.tutiworks.orm.Role</class>
            <class>org.tutiworks.orm.User</class>   
            <properties>            
                <property name="kundera.nodes" value="localhost"/>
                <property name="kundera.port" value="9160"/>
                <property name="kundera.keyspace" value="afrikana"/>
                <property name="kundera.dialect" value="cassandra"/>
                <property name="kundera.ddl.auto.prepare" value="update"/>
                <property name="kundera.client.lookup.class" value="com.impetus.client.cassandra.pelops.PelopsClientFactory" />
                <property name="kundera.cache.provider.class" value="com.impetus.kundera.cache.ehcache.EhCacheProvider"/>
                <property name="kundera.cache.config.resource" value="/ehcache-cassandra.xml"/>                 
            </properties>       
        </persistence-unit>
    </persistence>

And the configuration class creating the entityManager looks like:

            @Configuration
    public class SpringDataConfig extends WebMvcConfigurerAdapter{

        @Autowired
        private Environment env;

        @Value("${kundera.nodes}") private String node;
        @Value("${kundera.port}") private String port;
        @Value("${kundera.keyspace}") private String keyspace;
        @Value("${kundera.dialect}") private String dialect;
        @Value("${kundera.ddl.auto.prepare}") private String dbGenerator;
        @Value("${kundera.cache.provider.class}") private String cacheClass;
        @Value("${kundera.client.lookup.class}") private String lookupClass;
        @Value("${kundera.cache.config.resource}") private String configResource;
        @Value("${persistence.unit.name}") private String persistenceUnitName;

        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
            LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
            em.setPersistenceUnitName(persistenceUnitName);
            return em;
        }

        @Bean
        public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
            return new PersistenceExceptionTranslationPostProcessor();
        }
    }

The following class shows how the persistence context is used.

        public abstract class GenericDAO< T extends Serializable > {

           private Class<T> clazz;

           @PersistenceContext
           EntityManager entityManager;

           protected void setClazz( Class<T> clazzToSet ){
              this.clazz = clazzToSet;
           }

           public T findOne( String id ){
              return this.entityManager.find( this.clazz, id );
           }

           @SuppressWarnings("unchecked")
           public List< T > findAll(){
              return this.entityManager.createQuery( "from " + this.clazz.getName() )
               .getResultList();
           }

           public void save( T entity ){
              this.entityManager.persist( entity );
           }

           public void update( T entity ){
              this.entityManager.merge( entity );
           }

           public void delete( T entity ){
              this.entityManager.remove( entity );
           }
           public void deleteById( String entityId ){
              T entity = this.findOne( entityId );

              this.delete( entity );
           }
        }

A sample of the ORM that is mapped to a column family in Apache Cassandra installation looks like the following.

      @XmlRootElement(name = "Role")
    @Entity(name="Role")
    @Table(name = "roles", schema = "afrikana@cassandra_pu")
    public class Role implements Serializable {

        private static final long serialVersionUID = 9127322651789683331L;

        @Id
        @Column(name="id")
        @XmlID
        private String id;

        @Column(name = "role_name")
        @XmlElement(name = "role_name")
        private String roleName;

        public String getRoleName() {
            return roleName;
        }

        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }
    }

Where would I be going wrong with my configuration? What I'm I missing? How do I fix the error?

Was it helpful?

Solution

Kundera cassandra libraries are running on 1.2.4 version. Ideally 1.2.8 or higher versions should always be backward compatible, but in this case unfortunately they are not!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top