Simon Nicholls
Simon Nicholls

Reputation: 655

Weblogic JPA 2.1 Hibernate 4 Not Working java.lang.NoSuchMethodError

I've run into the classic issue of trying to run a web app on a weblogic server and running into errors because of the weblogic server having old copies of classes.

The main issue I run into is when trying to use JPA 2.1 I get the following issue:

weblogic.application.ModuleException: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;

The obvious answer here is that it is using the JPA version on the server which does not have that class.

I've set my weblogic.xml file to the following:

<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.7/weblogic-web-app.xsd">
<wls:weblogic-version>12.1.3</wls:weblogic-version>
<wls:jsp-descriptor/>
<wls:debug>true</wls:debug>
</wls:jsp-descriptor>
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>  
</wls:container-descriptor>
<wls:context-root>DiscoveryPortal</wls:context-root>
</wls:weblogic-web-app>

With the key line being: prefer-web-inf-classes: true

This seems to work for some classes but not all.

Upvotes: 3

Views: 8290

Answers (5)

st0ne_c0ld
st0ne_c0ld

Reputation: 127

Official answer: "While WebLogic Server 12.1.3 supports JPA 2.1, the Java Archive (JAR) files are not configured by default; some additional configuration is required to enable JPA 2.1 support. In this tutorial, the JPA 2.1 implementation is configured on the WebLogic Server classpath."

And solution for weblogic is here: http://www.oracle.com/webfolder/technetwork/tutorials/obe/fmw/wls/12c/01-06-004-JavaEE7andWebLogicServer/javaee7.html

you need to add:

PRE_CLASSPATH=/YOUR_MIDDLEWARE_HOME/oracle_common/modules/javax.persistence_2.1.jar:/YOUR_MIDDLEWARE_HOME/wlserver/modules/com.oracle.weblogic.jpa21support_1.0.0.0_2-1.jar
export PRE_CLASSPATH

to setDomainEnv.sh which is located in your domain folder under 'bin' directory.

Upvotes: 1

user1216927
user1216927

Reputation:

Placing following code into weblogic.xml

<container-descriptor>
    <prefer-application-packages>
        <package-name>javax.persistence.*</package-name> 
    </prefer-application-packages>
</container-descriptor>

seems to be enough for related expection, on WebLogic Server 12.1.2.0 if you have JPA 2.1 jar on your classpath.

Upvotes: 2

p3consulting
p3consulting

Reputation: 4670

I confirm that <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes> doesn't work with WebLogic12/Spring4/Hibernate4/HibernateValidator5/JPA2.1, you have to resort to <prefer-application-packages> but listing only java.persistence.* is far to be enough...

You have also to list:

javassist.*
org.hibernate.*
org.hibernate.validator.*
javax.validation.*

+ any other ones the Class Loader Analysis Tool will recommend you to include + include a ServletContextListener filter in your web.xml to register an "HibernatePersistencerProviderResolver implements PersistenceProviderResolver" that will return an singleton Collection holding an HibernatePersistenceProvider when called "getPersistenceProviders()"

  • if you are using Spring in your Spring applicationContext to support method validation: you need a bean "validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" and another one class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"

  • for your entityManager (class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean") jpaProperties: <prop key="java.persistence.transactionType">jta</prop> <prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WebLogicJtaPlatform</prop> <prop key="hibernate.event.merge.entity_copy_observer">allow</prop>

  • if you are using maven, in your pom.xml (if using another build system refer to its doc to do the equivalent set-up) you have to exclude org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec from the dependencies org.hibernate:(hibernate-core and hibernate-entitymanager) and then add it org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec but as a "provided" independent dependency.

and last but not least… DON'T use a persistence.xml ! not only with a LocalContainerEntityManagerFactoryBean you don't need it anymore but it will mess-up with WebLogic too and if you need to generate a DDL you can't use hbm2ddl anymore since the hibernate maven plugin is no more compatible with JPA2.1, you have to use an EntityManagerFactoryBuilder.generateSchema()... (not Persistence.generateSchema(...) as you will find when googling: this doesn't work without a persistence.xml...)

Upvotes: 0

Display Name is missing
Display Name is missing

Reputation: 6227

Weblogic 12c (supposedly) allows class filtering in both .war and .ear files. I would recommend moving from:

<wls:container-descriptor>
  <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>  
</wls:container-descriptor>

to:

<prefer-application-packages> 
  <package-name>javax.persistence.*</package-name> 
</prefer-application-packages> 

<prefer-application-resources> 
  <resource-name>javax.persistence.*</resource-name> 
  <resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
</prefer-application-resources>

The filtering seems to work much better than prefer-web-inf-classes.

See the Oracle docs here that says it works for .war files. If not, you may consider switching to an .ear to see what happens.

Upvotes: 5

Neil Stockton
Neil Stockton

Reputation: 11531

so you have inconsistent JPA API jar and Hibernate jars in the CLASSPATH. JPA API 2.1 brought in that method and Hibernate 4.3 would be required to support that IIRC

Upvotes: 0

Related Questions