0

How does JVM loads the class when we use one of two options extract or package required libraries while creating runnable jar in eclipse click for details.

Today I ran into an issue, where my main application was using hibernate-core.jar but one of thee jar my main application was depending on was using hibernate-core-5...jar, when this dependent jar was build using 2nd option (package), everything was working properly but when I switched to 1st option to build this jar (extract) I started getting below error.

Caused by: java.lang.ClassCastException: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider cannot be cast to org.hibernate.engine.jdbc.connections.spi.ConnectionProvider

As per SO this happens because of version mismatch and I think its exactly happening with me when I used extract option to build the jar.

My main application uses spring+hibernate(3) but my dependent jar just uses hibernate(5).

What I can interpret from the logs is connectionProvider(hibernate 5) can not be instantiated using LocalDataSourceConnectionProvider (hibernate 3). may be implementation for hibernate 5 is not getting loaded into JVM.

Does packaging .class files or .jar in runnable jar changes the way how classes loaded in JVM?

Akshay Naik
  • 669
  • 1
  • 6
  • 22
  • What do you mean "extract"? Package is a maven goal. "extract" is not. – Michael Apr 14 '20 at 10:56
  • Spring Boot packages dependencies in a specific way, where there is basically a lib directory containing all the library JARs. It has a special classloader which knows how to descent into this directory and load classes from those JARs. If you have a different way of creating a JAR, it is unlikely to follow the same format as Spring's. If the format is different, the way classes are loaded may also be different – Michael Apr 14 '20 at 11:00
  • @Michael, I am not using spring boot, its classic spring MVC application. and the dependency is console application which os exported as runnable jar from eclipse,. check the link from first paragraph for export details – Akshay Naik Apr 14 '20 at 14:09
  • If you're using "uberjar" (that is a single JAR artifact with all the dependencies) you can unzip it (things like Midnight Commander work too) and look inside to check what kind of dependencies are included. It's likely that both versions of hibernate are present in which case the behavior is unpredictable - it may break on some systems while work on others. – Juraj Martinka Apr 15 '20 at 07:37
  • @JurajMartinka This is what happening, its working on windows, not working on some linux servers but working on some linux servers, same code. – Akshay Naik Apr 16 '20 at 04:00
  • Did you check the content of the jar? – Juraj Martinka Apr 16 '20 at 05:03
  • @Juraj, although my dependency jar contains only hibernate-core5 jar but, my main application contains hibernate-core3.jar along woth dependency jar. – Akshay Naik Apr 16 '20 at 20:38
  • I will add dependency graph to explain it better. – Akshay Naik Apr 16 '20 at 20:38
  • I think the answer is hidden behind the logic of spring injects hibernate beans, when jar is created using extract method, spring class loader loads ConnectionProvider interface and injects hibernate object in another case, spring class loader does not because the interface is are not present in the current jar instead of in a bundled jar. – Akshay Naik Apr 19 '20 at 07:34

0 Answers0