javax.persistence jar is not loaded into tomcat - eclipse

I'm trying to run JPA servlet on Tomcat 8.
From my servlet I call method of a class named QueryDB.class located in another Eclipse project (JPA project, not WEB project).
But tomcat throws
SEVERE: Servlet.service() for servlet [MyRESTService] in context with path [/AutomationWeb] threw exception [org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: javax/persistence/Persistence] with root cause
java.lang.ClassNotFoundException: javax.persistence.Persistence
at java.net.URLClassLoader$1.run(Unknown Source)
...
Exception is thrown at line EntityManagerFactory emf = Persistence.createEntityManagerFactory( "AutomationDB_JPA" ); in QueryDB.class
I'm using Eclipse Mars with Maven. I have EclipseLink in my pom.xml defined:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.6.1</version>
</dependency>
I have following jars in my Application's WEB-INF/lib:
eclipselink-2.6.1.jar
javax.persistence-2.1.0.jar , it has javax/persistence/Persistence.class inside
There is no other SEVERE messages in the tomcat log.
What's wrong with this setup?
I also tried adding the persistence jar to apache-tomcat-8.0.28\lib , but got the same error.
Update: I moved Persistence.createEntityManagerFactory call to the servlet itself and got no classloader exception. So the question changes: why classloader used for QueryDB.class is different from servlet's classloader? Also, why classloader used in QueryDB.class does not see the Persistence.class, which is seen by the servlet's classloader?

Ok I've found a solution.
Excluded my JPA project from tomcat VM classpath
Converted my JPA project to the Utility project
Modified Deployment Assembly in my Web project properties so that it
will accept JPA project as .jar archive into WEB-INF/lib
I have no classloader exception anymore.

Related

Ojdbc8 jars upgrade to 21.1.0.0 throws Nosuchmethod exception UCPservletContextListener init

Ojdbc8, ons, ucp jars are upgraded to 21.1.0.0 version. When trying to start the app on tomcat server, it's throwing Nosuchmethod exception. Logged in the Tomcat's localhost.log file. Application tries to establish DB connection during startup itself.
01-Jun-2021 15:59:56.641 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log 3 Spring WebApplication Initializers detected on classpath
01-Jun-2021 16:00:05.365 INFO localhost-startStop-1 org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
01-Jun-2021 16:00:19.397 SEVERE localhost-startStop-1 org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [oracle.ucp.jdbc.UCPServletContextListener]
java.lang.NoSuchMethodException: oracle.ucp.jdbc.UCPServletContextListener.init
at java.lang.class.getConstructor(Unknown Source)
This is a known issue with ucp.jar in 21.1. It will be fixed in 21.3 when it's released. In the meantime, you can remove this class from the ucp.jar:
oracle/ucp/jdbc/UCPServletContextListener.class
From my experience, if you put jdbc/ucp jars to Tomcat's lib (which is recommended for productive system) and set provided scope for them in Maven, the problem will disappear.
Another option could be setting metadata-complete="true" in web.xml (read more here and here)
if you are using spring boot then you can use
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
this dependency or update your maven project.

Spring boot jackson auto configuration linkage error wildfly

A.war -> Is a simple spring boot REST app using version 1.2.6.RELEASE ( internally using spring 4.1.7 RELEASE, jackson 2.4.6 )
B.jar -> Is a wildfly9 shared module (stored in wildfly/modules) which is packaged using maven shaded plugin containing spring framework (without spring boot meaning using the old way of adding spring projects dependencies) and jackson classes of same version as above. (Its shaded because non-spring and non-container projects can just add this jar in their class-path and use it - it works)
A.war has maven dependency scope <provided> on B.jar and has jboss-deployment-structure.xml with <dependencies> <module name = "B"> </dependencies>
A.war deployment fails with below error.
Note: A.war deploys perfectly fine when i remove B.jar jboss dependency. So adding B.jar is causing this issue. And If i don't use spring boot in A.war (meaning if i use simple spring webmvc and context dependencies directly) with B.jar jboss dependency, A.war deploys perfectly too
Can anyone explain me what the error below says and how can i investigate more ?
As far as my understanding on wildlfy classloading, A.war and B.jar should be loaded in different module class loaders, Is A.war complaining about jackson classes of B.jar here in the error ?
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method
"org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.modulesToInstall([Lcom/fasterxml/jackson/databind/Module;)Lorg/springframework/http/converter/json/Jackson2ObjectMapperBuilder;"
the class loader (instance of org/jboss/modules/ModuleClassLoader) of the current class,
org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration,
and the class loader (instance of org/jboss/modules/ModuleClassLoader) for resolved class,
org/springframework/http/converter/json/Jackson2ObjectMapperBuilder,
have different Class objects for the type der used in the signature
at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration.configureModules(JacksonAutoConfiguration.java:259)
at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration.jacksonObjectMapperBuilder(JacksonAutoConfiguration.java:186)
at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration$$EnhancerBySpringCGLIB$$b993caa0.CGLIB$jacksonObjectMapperBuilder$1()
at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration$$EnhancerBySpringCGLIB$$b993caa0$$FastClassBySpringCGLIB$$5262bf2.invoke()
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318)
at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration$$EnhancerBySpringCGLIB$$b993caa0.jacksonObjectMapperBuilder()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ... 108 more
After investigating more jboss classloading behavior, jackson classes inside B.jar are conflicting with same jackson classes from jboss restesay module.
so after excluding them in jboss-deployment-structure.xml as below this problem is fixed..
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
<module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
</exclusions>

Jboss Wildfly EJB3 and Mybatis Deployment Error: NoSuchMethodError javax.persistence.Table.indexes()[Ljavax/persistence/Index;

I'm trying to deploy a EAR file to Jboss Wildfly (8.1.0) but im getting the following exception:
Caused by: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
My EAR file contains an EJB jar which contains mybatis (version 3.2.7) persistnence Units which have a Dependency on the cglib (version: 3.1).
This very same ear file deploy's and works without issues in JBoss 7 (version 7.1.1)
Based on the error saying the method isnt found but i know the class and method are there it must be some class conflict in the new version of jboss.
I managed to find the answer after some investigation and dissecting of the ear file. The problem was the asm.jar included in my EJB jar as a sub dependency of cglib. There is a class conflict between the jboss included jar and the EAR jar. To fix it simply add a maven exclusion on the cglib dependency for the asm sub dependency.
<exclusions>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
</exclusions>

How to debug NoSuchMethodError exception ? org.hibernate.cfg.Configuration.addAnnotatedClass(Ljava/lang/Class;)

When I try to initialize a Hibernate 4 SessionFactory in a servlet:
Configuration config;
ServiceRegistry registry;
SessionFactory factory;
config = new Configuration();
config = config.addAnnotatedClass(Star.class); // <-- Exception here.
I get an exception:
SEVERE: Servlet.service() for servlet [hu.adamsan.store.TestHibernate] in context with path [/TestProject] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoSuchMethodError: org.hibernate.cfg.Configuration.addAnnotatedClass(Ljava/lang/Class;)Lorg/hibernate/cfg/Configuration;
at hu.adamsan.store.TestHibernate.doGet(TestHibernate.java:75)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at
When I looked up in Google, I could not find a solution, but similar errors were present when there was a mismatch with the hibernate version. I've made a similar project, with the exact same maven dependencies, with the same code initializing hibernate in a doGet method, and it worked.
maven dependencies:
mysql-connector-java 5.1.26
hibernate-core 4.2.6.Final
hibernate-validator 5.0.1.Final
commons-beanutils 1.8.3
commons-collections 3.2.1
log4j 1.2.17
slf4j-api 1.7.5
Does anyone have an idea, what could be wrong?
Can someone offer general advice, how to handle, debug such obscure errors?
When you get a NoSuchMethodError in external libraries, it is usually due to having multiple versions of the same dependency on the classpath. This might be due to a transitive dependency, so detecting it through just looking at the dependency in the pom.xml of your project is not enough. If you do a mvn dependency:tree, it will list all transitive dependencies as well, so look for multiple versions of the same dependency.
It might also be that the same class is implemented is multiple dependencies, so google it to find out which jars contain it. http://www.jarfinder.com/index.php/java/info/org.hibernate.cfg.Configuration

Can't use JSTL in JSP page, with project that includes juel-impl jar because of ClassCastException with ExpressionFactoryImpl

The error is:
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception [Unable to compile class for JSP] with root cause
java.lang.ClassCastException: de.odysseus.el.ExpressionFactoryImpl cannot be cast to javax.el.ExpressionFactory
at javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:180)
at javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:107)
at org.apache.jasper.compiler.PageInfo.<init>(PageInfo.java:79)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:110)
.....
The project is using a war overlay, in which the overlaid project has the juel-impl jar, which is necessary for its use of shindig. Any way to use jstl in the child project jsp pages?
Seems you have two rivaling EL APIs in your class path, tomcat's and another one from your application. Your war file must not contain an el-api.jar or juel-api.jar. Make sure to exclude those dependencies.
The Juel 2.1.3 jar is a combination of the following Jars juel-impl.jar, juel-spi.jar and juel-api.jar.
We had the same issue when we included juel 2.1.3 jar in the pom and deployed in tomcat 7.
The issue is resolved by removing Juel 2.1.3 from pom and by adding only juel-impl.
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-impl</artifactId>
<version>2.2.6</version>
</dependency>
you need to also add
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-api</artifactId>
<version>2.2.6</version>
</dependency>
The juel 2.1.3 jar contains the javax/el interfaces and are also a part of jsp-api jar.
I hope this will help.