Issue
I am working on a java plugin that utilizes Hibernate JPA for my database interactions. I am using a Hibernate configuration file to accomplish this task.
When I export my project into a jar file and run it, I get the following error:
[23:23:12] [Server thread/ERROR]: Error occurred while enabling nationsatwar v1.1 (Is it up to date?)
java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
at net.mcnations.nationsatwar.PluginMain_Load.onEnable(PluginMain_Load.java:31) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:351) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at org.bukkit.craftbukkit.v1_16_R1.CraftServer.enablePlugin(CraftServer.java:493) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at org.bukkit.craftbukkit.v1_16_R1.CraftServer.enablePlugins(CraftServer.java:407) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at net.minecraft.server.v1_16_R1.MinecraftServer.loadWorld(MinecraftServer.java:438) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at net.minecraft.server.v1_16_R1.DedicatedServer.init(DedicatedServer.java:219) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at net.minecraft.server.v1_16_R1.MinecraftServer.v(MinecraftServer.java:810) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at net.minecraft.server.v1_16_R1.MinecraftServer.lambda$0(MinecraftServer.java:164) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at java.lang.Thread.run(Thread.java:830) [?:?]
Caused by: java.lang.ClassNotFoundException: org.hibernate.cfg.Configuration
at java.net.URLClassLoader.findClass(URLClassLoader.java:436) ~[?:?]
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:167) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:96) ~[spigot-1.16.1.jar:git-Spigot-0509002-6b95d59]
at java.lang.ClassLoader.loadClass(ClassLoader.java:588) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[?:?]
With the actual error being thrown on this line of code:
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
This immediately suggests my hibernate.cfg.xml
file is not being exported in the project. I checked the project files in the export wizard, and I could not even find the configuration file in the window.
(Note the missing hibernate.cfg.xml
file!!! (should be under the worldedit package))
Finally, in case its relevant, I am using the following dependency in my POM for Hibernate:
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.18.Final</version>
</dependency>
What am I doing wrong?
Solution
As stated Alex Funk in the comments:
java do not find org/hibernate/cfg/Configuration when trying to execute new Configuration
The problem is that the dependency is not packed into the jar file. Then, if you don't specify the .jar in the classpath and provide it at runtime, the JVM will not be able to create or access instances of classes of the dependency. In this case, the error indicates that the class org.hibernate.cfg.Configuration
is not found. So you have two approaches:
Approach 1. Create a jar with the dependencies (Bigger .jar but recommended)
To do this you must override the maven assembly plugin and configure it the following way:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>jar-with-dependencies</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Then you can generate the jar via:
mvn install
Approach 2. Add the hibernate into the .jar classpath and provide it on runtime
I do not recommend this approach because it breaks one of the main advantages of plugins. The user will have to download the library and place it in a lib folder in its server. So the plug-in will require more installation steps by the end-user instead or just 'plugging in' the plugin in the server plugins folder.
The maven configuration will be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.example.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Then in the server, users will have to provide the library jar into a lib folder inside the plugins folder:
MyServer
|--- plugins
| |--- lib
| |--- hibernate-core-5.4.18.Final.jar
| |--- YourPlugin-1.0.0.jar
|--- spigot-1.16.1.jar
... other server files and folders
Then execute:
mvn install
Let me know if this solves your problem!
Answered By - PauMAVA