Thursday, December 7, 2017

Eclipse Jar-in-Jar fails to find a joda.time class

Leave a Comment

Eclipse has 3 runnable JAR export methods. One of them does not work in my case. I want to stop using the export method that makes a library sub-folder and switch to a single JAR.

In all cases my invocation is in a script, with a few script variables such as $MEMORYOPTIONS

java $MEMORYOPTIONS -enableassertions -classpath VARIOUS-SHOWN-BELOW topLevelDomain.domain.packageName.className $1 $2 $3

Firstly...

I have success with the following export method and the class path as shown.

export > runnable jar > extract required libraries

-classpath /home/user/workspace/project/project1.jar

I have a reason for not wanting to use this single JAR. (It is because unpackaged third party packages expose files with duplicate names so I get annoying warnings. Example: A file called License.txt is in several packages.)

Secondly...

As already mentioned I also have success with the following "library sub-folder" export method and class path as shown.

export > runnable jar > copy required libraries into a sub-folder

-classpath /home/user/workspace/project/project1.jar:/home/user/workspace/project/project1_lib/*

(Edit: As it turns out the JAR has a manifest that points to the project1_lib subfolder so the class path can be simplified to omit that. Just delete the part after the colon (:) separator from the class path.)

Thirdly...

I interpret "package required libraries" to mean a JAR-in-JAR export. Invoked with the class path shown, this export results in a failure to find the class.

export > runnable jar > package required libraries

-classpath /home/user/workspace/project/project1.jar

The error is:

Exception in thread "main" java.lang.NoClassDefFoundError: org/joda/time/ReadablePartial

How do I get this particular type of Eclipse export to work? I have already uninstalled Eclipse (Mars) and reinstalled. I have also removed the org.joda.time package and added it back. The problem persists.

3 Answers

Answers 1

Did you consider creating an uber jar ?

With maven you just need to add the following plugin definition and use the command mvn package

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.2</version> <executions>     <execution>         <phase>package</phase>         <goals>             <goal>shade</goal>         </goals>         <configuration>              <filters>                 <filter>                     <artifact>joda-time:joda-time</artifact>                     <includes>                         <include>**</include>                     </includes>                 </filter>                 <filter>                     <artifact>*:*</artifact>                     <excludes>                         <exclude>META-INF/*.SF</exclude>                         <exclude>META-INF/*.DSA</exclude>                         <exclude>META-INF/*.RSA</exclude>                     </excludes>                 </filter>             </filters>         </configuration>     </execution> </executions> </plugin> 

Hope this helps.

Answers 2

You need to call the bundled JarRsrcLoader with your class as an argument:

java $MEMORYOPTIONS -enableassertions  -classpath /home/user/workspace/project/project1.jar  org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader topLevelDomain.domain.packageName.className 

However, this doesn't allow you to pass arguments ($1 $2 $3) to the called class.

Answers 3

You should launch your app using java's -jar option. Something like this:

java $MEMORYOPTIONS -enableassertions -jar /path/to/project1.jar $1 $2 $3 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment