How to include third party jars while running a java program - java

A very noob question.
I have a java class
package org.foobar;
import thirdparty_jar1;
import thirdparty_jar2;
public class FooBar{
public static void main(String[] args){
// some code
}
}
I use eclipse as my ide and I added these thirdparty jar 1 and jar 2 in its build path. and then I proceeded to export the jar.
Now I have a foobar.jar file and now I want to run it..
I did java -cp /path/to/foobar.jar org.foobar.FooBar
but it complains about missing third party libraries.
How do i run my jar (or probably build a fat jar) . I just want to run my program from command line.
Thanks

A jar has a manifest file called MANIFEST.MF, under the folder META-INF. This contains details about the jar file, the main class etc. Eclipse creates one by default, you can modify that or specify your own manifest file.
See http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html and Understanding the Default Manifest.
To add libraries to the classpath, you need to add the jar files' path to the manifest file, like this:
Class-Path: jar1-name jar2-name directory-name/jar3-name
See Adding Classes to the JAR File's Classpath

If you're using Maven, you can add this to your pom.xml file. This will create an additional "fat" jar whenever you build with Maven. It goes in the 'build.plugins' section:
<build>
<plugins>
...
<!--
The plugin below creates an additional, executable JAR with all dependencies
included in it.
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${package}.FooBar</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>

Since you said that you are using Eclipse, did you know you can export a runnable JAR and all its dependecies via the IDE? Right-click on your project and select Export. Search for "Runnable JAR". You should see this:
Now you have a few options:
Extract required libraries into generated JAR.
This will unpack the third party JARs and repack them, along with your class, into a single JAR.
Package required libraries into generated JAR.
This will include the third party JARs into your JAR, as well as some special Eclipse magic to unpack them when needed.
Copy required libraries into a sub-folder
This will copy the third party JARs into a folder and then update the manifest of your JAR, adding the third-party JAR relative file references to your classpath.

Related

Does a jar archive file created by `mvn package` neither contain its dependencies nor indicate which .class file contains main()?

After running mvn package to package compiled java program containing main(),
Is it correct that the created jar file doesn't contain dependencies, so when running the jar file, I still have to provide dependencies?
Is it correct that the created jar file doesn't indicate which .class file in it contains main() as the entry point, so when running the jar file, I still have to indicate the .class file which contains main()?
Thanks.
It depends. By default, the answer is yes, it does not contain this information.
But Maven can be configured to contain these things. To also include the dependencies, one could use the Maven Assembly plugin and bind it to the package phase with a jar-with-dependencies setting, or use the Maven Shade plugin (also bound to the package phase). They are similar, although I prefer the Shade plugin as it supports so-called transformers that can work around some issues one gets when combining multiple jar files into one.
To have a main-class defined as entry point, you can configure the Maven compile plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<mainClass>my.main.Class</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
If configured like that, you don't have to call java -cp my.jar my.main.Class arguments, but can just call it as java -jar my.jar arguments. If you still have additional dependencies, you would call it with java -jar my.jar -cp dependencies/*.jar arguments.

How to use a .jar file in the Terminal?

So I worked on a project and i coded everything in eclipse. I had my codes in folder called src and my libraries in a folder called lib. The problem is that, my code needs to be excecuted in the terminal. Well, now i get tons of errors. All of them are because there are libraries missing. I tried to import the .jar file from the lib folder to the src folder but the code still didn't work.
So, how can I "install" the libraries in the terminal?
btw. the library I'm trying to install is the com.google. I've already cloned it with the following line:
git clone https://github.com/google/gson
First of all, you have to make your project to compile perfectly with your IDE or whatever.
Later, you should create the runnable JAR file (with eclipse if you want, but it's important the world RUNNABLE jar file. Click in your project > Export > runnable jar file and select you main class in "Launch configuration".).
Finally, go to the console to the path of your JAR file and execute
java -jar file.jar
I think it should work :)
If you want to build your project from terminal, you need to make sure of two things.
1. You should have main class attribute in mainfest file.
2. Jar should be compiled with all the dependencies. (This will result in a bigger jar though)
You can do both with maven assembly plugin. Add the following in build/plugins in your pom.xml
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.tanmayvijayvargiya.MainApp</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Update the with your mainClass
To build the jar, run mvn package. This will generate jar in your target folder.
Next, to run the jar run java -jar target/jar-name-with-dependencies.jar
Source
Maven Assembly Plugin Usage

Build java project using jars into one jar (command line)

In Intellij, I'm able to "build an artifact" which allows me to create a jar file, even though my project uses other jar files (like drivers). Traditionally, I would compile a project with jar dependencies by putting them in my classpath like so:
javac -cp .:dependency.jar Main.java
and then be able to run Main by doing:
java -cp .:dependency.jar Main
My question is, how do I create a jar file file with this new Main? I can do:
jar cvf Main.jar Main.java
which will create a jar file, but it doesn't run and says:
no main manifest attribute, in Main.jar
I'd like to know how to package my other jar dependencies into on executable jar.
Option 1: Using Maven plug-in if you are using maven:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>Path.to.your.main.class</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
Option 2: Using spring boot to create fat jar. Which includes all your dependent jar files. Make sure you include spring boot dependency.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.3.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Option 3: Without any help of maven and Spring:
Create a manifest.txt file with the following content:
Main-Class: path.to.your.main.class
To create jar use command : jar -cvfm Application.jar manifest.txt /path/to/*.class

Manifest.mf remains empty when trying to write via maven build process

I am trying to write some extra data to my manifest.mf via the pom.xml but for some reason it is remaining blank....
I am a complete newbie at java so am going to write all my steps down here .. no matter how stupid this makes me look as i have no idea what i am doing so any pointers would be great...
This is the build part of my pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestFile>
${basedir}/src/main/resources/META-INF/MANIFEST.MF
</manifestFile>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Test>I am a test</Test>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
I have manually created the file MANIFEST.MF inside the src/main/resources/META-INF file and left it blank expecting it to writing during the build.
I run mvn clean package
I go into the target/resources/classes/META-INF dir and open MANIFEST.MF its blank.
When i go to the target/ and do
java -jar myTest.jar
the result is
no main manifest attribute, in myTest.jar
Would anyone please be able to tell me (very gently) what i am doing wrong
:D
thanks in advance
The maven pom.xml section looks good to me. You might want to use winzip or winrar to open the myTest.jar and check the MANIFEST.MF file inside the jar file under the target folder. Very likely your MANIFEST.MF file has already merged with the entries such as Implementation-Version for your project. The reason that target/resources/classes/META-INF/MANIFEST.MF is blank is because the merge has not happened yet. Maven at that time simply copied the MANIFEST.MF file you provided to the target folder. When you run java -jar myTest.jar, you got result "no main manifest attribute". That's because you did not specify <mainClass/> within the <manifest> section. If you do so, it will add a Main-Class entry in the MANIFEST.MF file, which will be the main class to be executed when you do java -jar myTest.jar

"No Main Manifest Attribute" in ----.jar Netbeans

I recently just started toying around with Maven in java. Time comes to test my project, it works fine in the NetBeans window, running the main class found in App.java (com.MyCompany.App), but when I try to run it from a command line I get an error:
java -jar fileName.jar
"No Main Manifest Attribute" in fileName.jar
I have tried adding a manifest.mf file specifying what main is, I've also been into project properties and added it as the main file...
What's going on?
You need the maven-jar-plugin (see Maven's example). This plugin will create the required entries in the manifest file when the project is built.
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
You need the version, otherwise, the project won't build. The fully.qualified.MainClass starts at the package hierarchy.
Hope there is a problem in your manifest file. Some basic checks might solve your problem.
it should under /META-INF/MANIFEST.MF
Content should have Main-Class:com.MyCompany.App
If you are using any IDE, there should be an option to export project as runnable jar, you can make use of that to let the IDE take care of correct manifest.
From command line jar cfm filename.jar Manifest.txt com/MyCompany/*.class which generates the Manifest file with following contents
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Main-Class: com.MyCompany.App
And then you can run jar command java -jar fileName.jar.
These type of problems are trivial but kills lot of time, just ensure your contents and location of the file is correct.
You could just use this for command line:
java -cp jarFileName.jar full.package.className
You wouldn't have to go into specifics of the Manifest file in this case.
Setting an Entry Point with the JAR Tool:
The 'e' flag (for 'entrypoint') creates or overrides the manifest's Main-Class attribute. It can be used while creating or updating a JAR file. Use it to specify the application entry point without editing or creating the manifest file.
For example, this command creates app.jar where the Main-Class attribute value in the manifest is set to MyApp:
jar cfe app.jar MyApp MyApp.class
You can directly invoke this application by running the following command:
java -jar app.jar
If the entrypoint class name is in a package it may use a '.' (dot) character as the delimiter. For example, if Main.class is in a package called foo the entry point can be specified in the following ways:
jar cfe Main.jar foo.Main foo/Main.class
If you look at the properties dialog for the project (from project tab, right click on your project and select properties) you'll see that there is a "run" item in the "Categories" window. Click on it and you'll see a dialog where you can specify the Main Class for the jar. That information will end up in your manifest.
I have been having this problem with Netbeans 8.0 and the built-in Maven project for the "Java Application" project prototype. Also I have Maven 3 and I found some of the suggestions on the web don't match the maven code used with Netbeans as well.
Anyway here's a simple recipe for having JAR file to run the main-class and embed dependent libraries. I made this work by comparing other project POM files for projects I found that worked with sub-project JAR-s so if someone with better Maven knowledge spots a gottcha, please speak. Also, I left in some normal stuff to provide context. Example follows:
<properties>
<packageName>trials.example</packageName>
<mainClass>${packageName}.CmdApp</mainClass>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4jVersion>1.7.7</slf4jVersion>
<log4jVersion>1.2.17</log4jVersion>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
This section tells Maven about the project.
packageName ... Is the Java package for the main-class
mainClass ..... The fully qualified name for class with main() method.
You will see these used in the maven-jar-plugin.
The other thing the built-in example prototype didn't do was to package my sub-projects into the JAR so I can run from the command line. This is done with the maven-dependency-plugin below. The interesting bit is in the where we don't need to package the system stuff, and we want the dependant classes wrapped into our JAR.
These are used as follows:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeScope>system</excludeScope>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
<packageName>${packageName}</packageName>
<addClasspath>true</addClasspath>
<classpathPrefix>classes/</classpathPrefix>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Hope that saves you the few hours of checking and testing to make it happen. Cheers, Will.

Categories

Resources