Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Combine Multiple Jars into One?

I've read so many articles/explanations on this and spent too many hours, but everything is either too broad or specific.

This question really only applies to an Applet I've made. It contains one Class, and requires 2 other Jar libraries. I've included these in the projects (multiple projects, because I've tried this in Netbeans and Eclipse...it's easy to recreate a one Class project). The point of all this is that my HTML/web project shouldn't have to deal with more than one Jar or reference them. It's not a complicated applet/project at all either.

Originally, I made it in Netbeans. It has the main package, and after adding the 2 Jars, they are put in a "Libraries" area (the "resources" folder). After building it, Netbeans creates a Jar for my one package/class, and then puts the 2 other libraries in a "lib" directory next to it. I'd like them to be in one, distributable Jar. From the many things I've looked through, I've tried putting the following in build.xml:

<target name="YourBigJar" depends="-post-jar">
  <jar destfile="dist/BigJar.jar">
    <zipfileset src="dist/cxapplet.jar"/>
    <zipfileset src="resources/dpotapi.jar"/>
    <zipfileset src="resources/dpotjni.jar"/>
  </jar>
</target>

But it produces nothing. I got this from NetBeans - deploying all in one jar . I don't know/understand how to use build.xml, so I wouldn't be surprised if something's going wrong (obviously), but I get no error/warning messages.

When I made it in Eclipse, it effectively combines them, but when I use the Jar in my actual web project, it says it cannot find the classes from the other 2 Jars. I wouldn't understand how to fix it, but is it a Classpath problem? In Eclipse, I make a new directory called "lib" and put the Jars in it. Then, I right-click the project, go to "Java Build Path", and add the Jars, also checking them under the "Order and Export" tab. From things I've read, I right-click the project, choose "Export", choose "Jar", uncheck the ".classpath" and ".project" files, only check "Export generated class files and resources", and then allow it to generate the manifest file. Like I said, this generates one Jar, but its contents are my package and then a "lib" directory that has the 2 other Jars. The Manifest is there, but it's pretty empty and doesn't reference any files (not sure if that's important). When I put it in my web app, it says the applet can't find the other classes.

It just seems so simple - one package/class, two external Jars...combine into one Jar when built for distribution as an applet. Any ideas?

UPDATE:

Since we started using Maven, someone looked into using a Maven plugin. So we ended up creating a new project to house the applet (since it's used across multiple projects), and used this in our pom.xml, in the end:

<build>
  <resources>
    <resource>
      <directory>${basedir}/applet</directory>
      <excludes>
        <exclude>codesignstore</exclude>
      </excludes>
    </resource>
    <resource>
      <directory>${basedir}/src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <version>2.2-beta-5</version>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <finalName>cxapplet</finalName>
        <archive>
          <index>true</index>
          <manifest>
            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
          </manifest>
        </archive>
        <appendAssemblyId>false</appendAssemblyId>
      </configuration>
      <executions>
        <execution>
          <id>make-my-applet-jar</id>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jarsigner-plugin</artifactId>
      <version>1.2</version>
      <executions>
        <execution>
          <id>sign</id>
          <goals>
            <goal>sign</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <keystore>${basedir}/applet/codesignstore</keystore>
        <alias>codesigncert</alias>
        <storepass>HIDDEN</storepass>
        <keypass>HIDDEN</keypass>
      </configuration>
    </plugin>
  </plugins>
</build>

And it was nice because it allowed us to use our Code Signing Certificate to automatically sign it too.

like image 481
Ian Avatar asked Jan 16 '13 01:01

Ian


1 Answers

First of all, let me say that there really is no reason to combine the jars - you can deploy an applet using your class file (not in a jar) and its separate dependent jars.

However, if you feel that you must make one big jar out of your class and all of its dependencies, then you can do so.

You can't put jar files into another jar file, however - jar files don't work that way. What you need is for all of the contents of all of the jar files to be extracted, and then zipped up again into one jar.

If you're going to do this, I would suggest using the Maven build tool to do it. Once you set up your build with Maven, you can configure the Maven Assembly Plugin to build one big jar for you.

I know that Eclipse supports Maven, and I assume that NetBeans does as well.

like image 66
GreyBeardedGeek Avatar answered Oct 22 '22 04:10

GreyBeardedGeek