Improvement of Java application deployment experience with IDEA
I have a Java project, which based on multiple third-party Java libraries (JARs) when I run this application inside of IDEA everything is OK and works.
The project structure is:
Project folder:
— .idea
— LIBS //third-party libraries
— MODULE // my module with sources
Now I want to deliver the application to the customer as a one solid JAR file, which should be executed with java -jar myApp.jar. I defined attributes, specified the main class, and classpath and generated a JAR. I checked inside of this JAR, it contains all third-party libraries I use in my application.
The problem is when I execute this JAR it returns error «Can't find third-party libraries» but when I put the LIBS folder in the same folder where my JAR is stored, everything is working.
My propose/suggestion:
Is it possible to implement in IDEA the built-in feature, which will generate ready-to-use JAR file, which will not require from the user to deal with third party libraries? It will be cool if IDEA could generate the JAR file I can send to a customer, which could run it without any movements, just call java -jar myApp.jar.
Of course, I can try to deal with some approaches as One-JAR but it will be great if IDEA could do it for me automatically.
Thanks.
Please sign in to leave a comment.
This should work when creating a jar artifact from modules with dependencies when "extract to the target JAR" option is selected.
That's exactly what I did before I opened this topic.
My third-party modules:
My artifacts settings:
The error I get when I execute JAR file:
Please share a sample project to reproduce. Maybe your manifest file overrides the classpath.
OK, I'll upload a demo-version of the project to Google Drive.
The link will be published here during the coming weekend.
I explored the issue more deeply and found out that the problem is not with the attached JAR-file but with external file, which third-party library loads.
For instance, if I execute my app from IDEA, I get:
The application is able to load the marked file.
But when I execute JAR, I get:
Here we can see that the application is not able to load the file. I checked the content of my JAR file and see that this JAR doesn't contain the wanted external file.
The Project structure → Libraries contains:
The path LIBS\NLPCORE\NER contains the wanted files.
It's strange why IDEA doesn't include to JAR all files, which are stored inside of the folders, that I added to Project Libraries.
I'll upload the demo-project on Sunday, 5th June.
Edit the artifact to include this directory content in the desired location inside the target directory.
I already tried this:
I defined in artifacts settings the folder structure of LIBS\NLPCORE\NER\classifiers, which contains the wanted files and re-created the JAR. Still the same error.
Perhaps the external lib doesn't look for those files inside the JAR, expecting them to be accessed through the fil system. Do you know how the library loads those files?
-JM
Jean is right. The library expects to load the files from the file system, not from classpath, so the directory should reside outside of the jar. However, jar artifact configuration doesn't allow to move the directory above the jar.
What you can do is to create yet another artifact with the type Other, then click + to add Artifact to this one, choose your existing jar artifact, then click + and add Directory Content. This way you will have a directory containing the jar with all the dependencies inside, plus a directory next to the jar with the files that have to be loaded from the file system instead of the classpath:
Great! It works!
Thank you a lot for the clarification.
It will be great if IDEA could somehow simplify & automatize such process.
One more question, currently I have my JAR, which I execute and the folder LIBS\NLPCORE\NER\classifiers with wanted files.
Everything is working but I would like to pack these two objects (JAR and LIBS) into one solid JAR, is it possible?
It's not possible unless you modify the library code so that it loads the files from classpath instead of the file system.
Understood.
Thank you for the consultation and detailed explanation.