Tuesday, November 4, 2014

Create Executable Jar from IntelliJ Java Project

Summary

  • Define Jar file Components
  • Build Jar file
  • Run command

Define Jar file Components

File | Project Structure...
Select Artifacts in left side under Project Settings
  • Click "+"
  • Select "jar"
  • Choose "From modules with dependencies"
  • Select the class with your executable main method.

Build Jar file

Build | Build Artifacts...
  • Under "Build Artifact", choose the jar file that you defined earlier
  • Under "Build", click "Build"
The jar file can be found in the /out/artifacts/_jar directory

Run command

If your project name is "ijtest" the command to execute your jar would look something like this:

$ java -jar /Users/lex/dev/java/ijtest/out/artifacts/ijtest_jar/ijtest.jar

Notes

You can pass parameters, too.

$ java -jar /Users/lex/dev/java/ijtest/out/artifacts/IJTest_jar/ij.jar --parm1=ONE --parm2=TWO


Troubleshooting

First, make sure you are running a recent version of InjelliJ.

I'm running InjelliJ Community Edition v14.0.2

Next, make sure the sdk you've configured in IntelliJ is consistent with the one you use on your console.

This is what happens when your IntelliJ JDK is version 1.7 but your java in your console is version 1.6...


~/dev/java $ java -jar /Users/lex/dev/java/ijtest/out/artifacts/ijtest_jar/ijtest.jar
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/company/Main : Unsupported major.minor version 51.0
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
 at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
 at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
~/dev/java $ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)
~/dev/java $ find /Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home -name java
/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/bin/java
/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/bin/java
~/dev/java $ /Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/bin/java  -jar /Users/lex/dev/java/ijtest/out/artifacts/ijtest_jar/ijtest.jar
~/dev/java $ /Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/bin/java  -jar /Users/lex/dev/java/ijtest/out/artifacts/ijtest_jar/ijtest.jar
hello, world!


Profit!

Here we run the jar, from the console, that I we just created using the steps outlined above...

~/dev/java/ijtest/out/artifacts/ijtest_jar $ ls -lrt
total 24
-rw-r--r--  1 lex  staff   968 Jan  5 22:56 ijtest.jar
drwx------  4 lex  staff   136 Jan  5 22:57 ijtest
-rw-r--r--@ 1 lex  staff  6148 Jan  5 22:57 .DS_Store
~/dev/java/ijtest/out/artifacts/ijtest_jar $ jar xf ./ijtest.jar
~/dev/java/ijtest/out/artifacts/ijtest_jar $ ls -lrt
total 24
drwxr-xr-x  3 lex  staff   102 Jan  5 22:56 com
drwxr-xr-x  3 lex  staff   102 Jan  5 22:56 META-INF
-rw-r--r--  1 lex  staff   968 Jan  5 22:56 ijtest.jar
drwx------  4 lex  staff   136 Jan  5 22:57 ijtest
-rw-r--r--@ 1 lex  staff  6148 Jan  5 22:57 .DS_Store
~/dev/java/ijtest/out/artifacts/ijtest_jar $ find .
.
./.DS_Store
./com
./com/company
./com/company/Main.class
./ijtest
./ijtest/com
./ijtest/com/company
./ijtest/com/company/Main.class
./ijtest/META-INF
./ijtest/META-INF/MANIFEST.MF
./ijtest.jar
./META-INF
./META-INF/MANIFEST.MF


Notice that all files exist in the jar file, including MANIFEST.MF.

References

http://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/

This work is licensed under the Creative Commons Attribution 3.0 Unported License.

8 comments:

  1. does't work.

    no main manifest attribute, in xxx.jar

    ReplyDelete
  2. zhaoyou, I tried the steps that I originally outlined above and did not see the issue you mentioned. I updated the article with more information that will hopefully help. ~ Lex

    ReplyDelete
  3. Also followed instructions, jar does not come with manifest file.

    ReplyDelete
  4. Same here. No Manifest file into my created jar.

    ReplyDelete
  5. Okay, this seems to be an old bug in intellij.

    https://youtrack.jetbrains.com/issue/IDEA-99596

    The workaround at the bottom of the page fixes the issue. You can also create a folder named "META-INF" into your output jar and tell intellij to copy your manifest from your source directory into it. This fixed it for me.

    ReplyDelete
  6. My generate jar file failed. Here is the output from the command pane
    Exception in Application start method
    java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
    Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Unknown Source)
    Caused by: java.lang.IllegalStateException: Location is not set.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at org.Michael.Control.Main.initRootLayout(Main.java:109)
    at org.Michael.Control.Main.start(Main.java:70)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    ... 1 more
    Exception running application org.Michael.Control.Main
    Lines at main
    70 is initRootLayout();
    109 is rootLayout = loader.load();
    The context is
    public void initRootLayout() {
    try {
    // Load root layout from fxml file.
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(Main.class
    .getResource("../View/RootLayout.fxml"));
    rootLayout = loader.load();
    ...
    Can you help?

    ReplyDelete