Improvement of Java application deployment experience with IDEA

Answered

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.

13 comments
Comment actions Permalink

This should work when creating a jar artifact from modules with dependencies when "extract to the target JAR" option is selected.

0
Comment actions Permalink

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:




 

0
Comment actions Permalink

Please share a sample project to reproduce. Maybe your manifest file overrides the classpath.

1
Comment actions Permalink

OK, I'll upload a demo-version of the project to Google Drive.
The link will be published here during the coming weekend.

0
Comment actions Permalink

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.

0
Comment actions Permalink

Edit the artifact to include this directory content in the desired location inside the target directory.

0
Comment actions Permalink

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.

0
Comment actions Permalink

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

1
Comment actions Permalink

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:

1
Comment actions Permalink

Great! It works!

Thank you a lot for the clarification.

It will be great if IDEA could somehow simplify & automatize such process.

0
Comment actions Permalink

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?

0
Comment actions Permalink

It's not possible unless you modify the library code so that it loads the files from classpath instead of the file system.

1
Comment actions Permalink

Understood.

Thank you for the consultation and detailed explanation.

0

Please sign in to leave a comment.