How can I build an executable JAR from a project (including neccessary libraries)?

I was planning to create an executable JAR from a project, and was a bit surprised that this seems to be a problem in IntelliJ IDEA (I am using version 9.0.1). In Eclipse, you can "Export" your project with dependencies, and recieve an executable JAR, which allows the user to deploy an application in a single file. From what I've understood so far it seems, Eclipse unpacks all JARs into one hierarchy, and repacks the result, as the Java classloader wouldn't be able to find classes in JARs packed into another JAR. In Netbeans, you have the possibility to have the IDE create an executable JAR file and a lib folder that contains all JARs the application depends on.

After some reading (and Googling)I found out about the "Artifacts" feature. I can have the IDE put all dependent JARs into the project JAR, but all I manage is to have the dependency JARs packed into the project JAR, where the classloader won't be able to access them.

Is there any way of getting such an executable JAR?


For those people who are encountering the same problem I can only offer the following workaround:

  • Set up your project as a Maven project
  • Add the following to your pom.xml (right under the <version>x.y</version> tag):
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.0.2</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                        <encoding>${project.build.sourceEncoding}</encoding>
                        <showDeprecation>true</showDeprecation>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.2-beta-5</version>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <mainClass>MyProjectName</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
  • (I think this is optional) Open the Run Configuration Editor (Run -> Edit Configurations). In the panel "Before launch" make sure the box "make" is checked.
  • In the "Maven Project" control panel (accessible at the right border of the IDE window) expand the Lifecycle goals, right-click "install" and check "Execute before Make" (by choosing "before make" I was hoping to avoid the sources being compiled twice, but I'm not sure of that. Anyone can answer that? However, "after make" will work as good...)
  • In your output folder ("target") you will find a JAR named "MyProjectName-x.y-jar-with-dependencies.jar" that can be invoked by double clicking or from the command line with "java -jar MyProjectName-x.y-jar-with-dependencies.jar"


I hope this is helpful ;-)

Any comments (or corrections of course) are greatly appreciated!!!


Kind regards,
Jens

3 comments

There are two problems here. Firstly artifacts doesn't allow to include unpacked jars (see http://youtrack.jetbrains.net/issue/IDEA-51729) so you
cannot create a single executable jar with all dependencies included in it. You can create an artifact containing jar file with your classes and
dependent jars placed outside it but now you need to configure such artifact by hand. There is a feature request to support automatic creation of such
artifacts (http://youtrack.jetbrains.net/issue/IDEA-25719) and we'll try to implement it in one of 9.0.x updates.

I was planning to create an executable JAR from a project, and was a bit surprised that this seems to be a problem in IntelliJ IDEA (I am using version 9.0.1). In Eclipse, you can "Export" your project with dependencies, and recieve an executable JAR, which allows the user to deploy an application in a single file. From what I've understood so far it seems, Eclipse unpacks all JARs into one hierarchy, and repacks the result, as the Java classloader wouldn't be able to find classes in JARs packed into another JAR. In Netbeans, you have the possibility to have the IDE create an executable JAR file and a lib folder that contains all JARs the application depends on.

After some reading (and Googling)I found out about the "Artifacts" feature. I can have the IDE put all dependent JARs into the project JAR, but all I manage is to have the dependency JARs packed into the project JAR, where the classloader won't be able to access them.

Is there any way of getting such an executable JAR?


For those people who are encountering the same problem I can only offer the following workaround:

  • Set up your project as a Maven project

  • Add the following to your pom.xml (right under the <version>x.y</version> tag):

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2-beta-5</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>MyProjectName</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

  • (I think this is optional) Open the Run Configuration Editor (Run -> Edit Configurations). In the panel "Before launch" make sure the box "make" is checked.

  • In the "Maven Project" control panel (accessible at the right border of the IDE window) expand the Lifecycle goals, right-click "install" and check "Execute before Make" (by choosing "before make" I was hoping to avoid the sources being compiled twice, but I'm not sure of that. Anyone can answer that? However, "after make" will work as good...)

  • In your output folder ("target") you will find a JAR named "MyProjectName-x.y-jar-with-dependencies.jar" that can be invoked by double clicking or from the command line with "java -jar MyProjectName-x.y-jar-with-dependencies.jar"


I hope this is helpful ;)

Any comments (or corrections of course) are greatly appreciated!!!


Kind regards,
Jens

---
Original message URL: http://www.jetbrains.net/devnet/message/5259520#5259520



--
Nikolay Chashnikov
Software Developer
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"

0

Hello, 

I manually build jar from build.gradle -> task buidJar(type:jar) {}

Is there a way to automate that call directly from the terminal?

Thank you in advance,

Phil

0

seems like $gradle buildJar ... :)

0

Please sign in to leave a comment.