Java - jar with librairies included - java

I am currently trying to make a Jar with all my libraries included.
What I have done.
I have created folders like this :
main folder
class (which contain all my classes)
ressources (containing all my libraries : mongo, jedis...)
MANIFEST.MF
My main class is named process.
My manifest is like this:
Main-Class: process
Class-Path: ressources\commons-pool-1.5.6.jar ressources\jedis-2.0.0.jar resources\mongo-2.6.3.jar class
I have generated the JAR with this command :
jar cvmf MANIFEST.MF process.jar class/*.class ressources/*.jar
My problem : When executing the JAR I have still the message
Exception in thread "main" java.lang.NoClassDefFoundError: process
Any ideas ?

Are you using eclipse? If yes, it have an option in export to export libraries together with jar..
with netbeans, I dont know how to do it.

You could build your jar with Ant using zipfilesets to copy in the content of the other jars (rather than the jars themselves), or you could take a look at jarjar which does that and more.

Eclipse: You have to add the external jar files to the build.properties, otherwise they are no tpart of the generated jar file.
Ar the libraries included in the jar file, you have generated?

Related

Java export running jar w/ project

So, I've added a git repo to my project (sjxlsx). I've then right-clicked the repo and imported into the package explorer. I then went to Project->Build path in order to make sure it's on "Required projects on the build path".
When I debug on Eclipse, works just fine.
I'm now trying to export as a running jar and when I execute it outside of Eclipse, it somehow is giving an error (empty.xlsx not found). That is, because in the XLSXWriterSupport, the open method is fetching this empty.xlsx file. On debug, it's working as expected but on converting to a running jar, it's giving me this error.
This is due to this 'empty.xlsx' file being on the resources of the other project. How can I solve this?
https://github.com/davidpelfree/sjxlsx/blob/master/src/main/java/com/incesoft/tools/excel/support/XLSXWriterSupport.java
This is because a resource on the class path is not a File on the file system.
Here it is packed in a jar (zip format).
The wrong code:
if (getClass().getResource("/empty.xlsx") == null) {
throw new IllegalStateException("no empty.xlsx found in classpath");
}
workbook = new SimpleXLSXWorkbook(new File(getClass().getResource("/empty.xlsx").getFile()));
As SimpleXLSXWorkbook has only a File constructor (AFAIK), you need to create a temporary file.
Path tempPath = Files.createTempFile("sjxlsx-", ".xlsx");
Files.copy(getClass().getResourceAsStream("/empty.xlsx"), tempPath);
workbook = new SimpleXLSXWorkbook(tempPath.toFile());
Better have some provision to delete temp files, for instance creating them in a specific directory, see Files.
You probably have the Eclipse Project build path configured to use absolute library references. When you try to run your runnable jar, the jvm cannot find the required dependencies.
Edit:
If you want to export your software as a RUNNABLE jar file, then the jar must contain a MANIFEST file which specifies the dependencies and main class. Example:
Manifest-Version: 1.0
Main-Class: com.example.Main
Class-Path: lib1.jar lib2.jar
(assuming your main class is com.example.Main)
In order to run your runnable jar file, place lib1 and lib2 on the same directory as your runnable jar and run:
java -jar myJar.jar
Otherwise you could just compile your main class and run it like this (assuming lib1 and lib2 are copied into a lib/ dir on your main class root path):
java -cp '.:/libs/*.jar' com.example.Main
You could also use a dependency manager tool such as maven and configure your build to create an "uberJar":https://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html
uberJars contain all your software dependencies in one heavy runnable jar file.
Hope this helps.

jar file works in eclipse folder but not out of it.Main class notfound

My groovy (ant1.8.1 for build)project was build in jdk1.5 and now i am making some changes and upgrading to jdk1.8 .
When i build and make jar ,it works fine from the folder where code is in eclipse.
but when copy that jar and try to run get below-
Error :could not find or load main class Run.
Rest all jars are as below(same as used in jdk5)
groovy-all-1.6.9.jar
commons-codec-1.4.jar
commons-httpclient-3.0-rc4.jar
commons-logging-1.1.1.jar
commons-net-2.0.jar
lib/log4j-1.2.15.jar
jtds-1.2.5.jar
httpmime-4.0.1.jar
When you say "run", I understand you mean something like:
java -jar MyJar.jar
You should check your MANIFEST file inside the JAR and make sure your Main-Class is defined as you need.
Main-Class: pakage.name.ClassName.class
And the corresponding pakage.name.ClassName.class exists in your jar file (or is included in any of the libraries accessible through classpath)
Check this anyway Setting application entry point

ClassNotFoundException when using a self-created jar file

Using Eclipse I created some parser classes I want to provide to another project as a jar archive for validation purposes. So the parser project look like this:
ParserProject
- src
-- com.package.x
--- ClassA
--- ClassB
- lib
-- external1.jar
-- external2.jar
The ClassA and ClassB use the external jar archives, like Jackson or some Apache commons. To provide the functionality to another project, I exported the entire project as jar archive and executable jar archive (Right click on project > Export... > Java > JAR file > Select all files and "Export generated class files and resources" > Finish).
The jar file is created without any errors. When I use the parserproject.jar in my validation project, I can access all my methods using auto completion, but when I run the validation project, I get a java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonParseException.
Now three strange things:
All jackson jars are included in the parser project. Besides, I can run a main() method in the parser project and everything works fine, no ClassNotFoundException occurs.
When I add the parserproject.jar to my validation project in the class path and open the jar archive in the Package Explorer, the parserproject.jar seems to contain all jars it needs.
For the executable jar archive, all required external jars are contained in the MANIFEST.MF (Package Explorer > validation project > Referenced Libraries > + besides parserproject.jar > META-INF > MANIFEST.MF). It looks like this:
Manifest-Version: 1.0
Rsrc-Class-Path: ./ json-20140107.jar jackson-annotations-2.5.4.jar ja
ckson-core-2.5.4.jar jackson-databind-2.5.4.jar commons-io-2.4.jar co
mmons-validator-1.3.1.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar
json-schema-validator-2.2.6.jar jackson-module-jsonSchema-2.4.4.jar
juniversalchardet-1.0.3.jar snakeyaml-1.15.jar commons-beanutils-1.7.
0.jar commons-digester-1.6.jar commons-logging-1.0.4.jar joda-time-2.
8.1.jar jopt-simple-4.6.jar jsr305-3.0.0.jar json-schema-core-1.2.5.j
ar libphonenumber-6.2.jar jackson-coreutils-1.8.jar commons-lang-2.6.
jar guava-16.0.1.jar msg-simple-1.1.jar btf-1.2.jar mailapi-1.4.3.jar
uri-template-0.9.jar
Class-Path: .
Rsrc-Main-Class: com.package.SchemeValidator
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
I get the exception if and only if I use the generated jar file in my validation project. In case I get rid of the parserproject.jar and define a dependency to the ecplise parser project instead (Right click on validation project > Properties > Java Build Path > Projects) I do not get the ClassNotFoundException.
So now my question is, how I should export the jar so that every class is found. Thank you!
Eclipse only takes care of the compile-time dependencies while generating a .jar
Since your generated .jar can be moved to virtually anywhere, the dependencies must again be present during execution time.
You have two options:
Execute your jar with the -jar option, while leaving all
dependencies in the same folder. Since your manifest uses "./" as classpath, this means all dependencies must be on the same directory you are executing your jar from. NOTE classpath is relative to the directory you are executing from, not the directory the file is on.
Execute your jar withour the -jar option, and specify the -cp option to point to the dependencies, and the specify the main class.
java -cp "<path to your jar>;<path to dependency 1>;<path to dependency 3>[;...]" <your main class>
You might consider creating a so called fat jar which will contain all the needed classes. For example: http://fjep.sourceforge.net/
If you do not want to go through the hassle of managing all the depencencies by yourself, consider using a build tool like
Maven https://maven.apache.org/ or Gradle https://gradle.org/.

How to package required external libraries AND sources in Eclipse

I have an issue that is really annoying right now.
For a school project (that is due on monday :( ), I have to submit a .JAR file that is a stand alone app and that includes sources.
However, in Eclipse, I didn't find how to export the sources and at the same time, include the required libraries.
My BuildPath is set up this way :
http://image.noelshack.com/fichiers/2014/19/1399746312-owp08.png
When I do :
Export as a runnable JAR file, everything works in my program but I don't have the sources inside the JAR
Export as a JAR File, I can add my sources, but when i try to run the JAR file, I have this exception :
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
Here are my settings :
http://image.noelshack.com/fichiers/2014/19/1399746469-sans-titre.png
I really don't know what to do, I've been searching for hours now, can someone help me ?
Thank you in advance.
Regards,
Azsde.
Well, the short answer is that eclipse doesn't support doing that directly. This is why most people use other tools such as Ant or Maven in their projects, rather than relying on the IDE.
You can work around eclipse's lack of an export source option in the runnable jar export wizard in one of two ways:
You can create a runnable jar and then manually add your source files to it
You can create a normal jar which includes your source files and add a MANIFEST.MF file to it.
Adding source files manually
This is what I would normally consider a terrible option, but since this is a homework assignment, there are two mitigating factors:
this is a one-off
you are short on time
If you have neither the time nor inclination to learn the details about manifests, I would recommend this option.
Adding your own MANIFEST.MF
As you may have noticed, even when you select the option to have eclipse generate your manifest in the export wizard, your jar file won't actually run. If you open up the 'normal' jar file and look at the generated manifest file it will look something like this (for a simple HelloWorld program using one third party library):
Manifest-Version: 1.0
Main-Class: HelloWorld
Whereas if you open up the manifest file for an exported runnable jar it will look something more like this (for the same program):
Manifest-Version: 1.0
Rsrc-Class-Path: ./ commons-lang3-3.3.1.jar
Class-Path: .
Rsrc-Main-Class: HelloWorld
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
As you can see, the generated manifest file is failing to include support for third party libraries.
What you would need to do in this case is write your own manifest file and keep it as a resource in your project. Then do a normal jar export, and on the last page of the wizard select the Use existing manifest from workspace option, and point it at your own manifest file.
This will have the advantage that you can export a new runnable jar whenever you like, including your source files, and without requiring manual tinkering each time.
If you're interested in working with manifest files, there's a good tutorial on oracle's website here that can help you get started:
http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html

java.lang.NoClassDefFoundError thrown when running jar file

I am trying to run my jar file on a Mac (Haven't yet tried on any other platform). When I run using java -jar MyApp.jar I get the following error
Stacktrace:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
at tabalchi.MyLogger.getLogger(MyLogger.java:51)
at tabalchiApp.TabalchiApp.printSystemProps(TabalchiApp.java:117)
at tabalchiApp.TabalchiApp.main(TabalchiApp.java:37)
So, as you can see the main class is recognized.
This is the manifest file.
--->
Manifest-Version: 1.0
Class-Path: . jars/log4j-1.2.16.jar jars/jfugue-4.1.0-20120125.jar jars/gervill.jar jars/AppleJavaExtensions.jar
Main-Class: tabalchiApp.TabalchiApp
SplashScreen-Image: tabalchiApp/resources/splash.png
<---
And the folder structure in the jar file as follows.
--->
META-INF/MANIFEST.MF
jars/AppleJavaExtensions.jar
jars/gervill.jar
jars/jfugue-4.1.0-20120125.jar
jars/log4j-1.2.16.jar
tabalchiApp/TabalchiApp.class <-- this is the main class
tabalchiApp/otherClasses.....class
<---
I have read many posts about running .jar file but none of the solutions have worked for me. I would really appreciate your help on this one.
I am creating the jar file by exporting from eclipse. If I export to a runnable jar file then I cannot control the making of the manifest file. I need to add the splash image in the manifest file. And I am having some other issues with the runnable jar export. Hence this path.
It seems that log4j is missing.it is expecting jars/log4j-1.2.16.jar in class path .
jars/log4j-1.2.16
should be under folder structure.
jars/log4j-1.2.16.jar
In which directory are you trying to use:
java -jar MyApp.jar
You can specify the packages/directories in the classpath to be sure they are found.
Ok, so according to this link,
http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file called MyUtils.jar, you cannot use the Class-Path header in MyJar.jar's manifest to load classes in MyUtils.jar into the class path.
So, it seems I cannot include other jar files in my jar file.

Categories