How to Combine Multiple Jars into One?
Asked Answered
C

2

13

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.

Causality answered 16/1, 2013 at 1:42 Comment(5)
"The point of all this is that my HTML/web project shouldn't have to deal with more than one Jar" It is trivial to do it so the browser can handle it. "Any ideas?" Deploy the Jars the usual way (that has advantages over your current strategy) & save yourself time.Nerynesbit
Its better to make dependencies of one jar to another.Many jar making tools makes your work easy.Limey
@joeyrohan I'm not sure what you mean, but that's why I'm trying to use Netbeans' and Eclipse's build tools, which I thought would do it, to accomplish this.Causality
@AndrewThompson So my main reason for posing this question is because I'm having trouble signing the Jars and the browser recognizing this. I know, the first step should've been to identify the problem with the signing, but everything in the Jar, if I extract and look through it, looks fine, so that's why I'm a little concerned with multiple Jars. Not sure if that's the actual cause, but I thought it could be organized better and possibly work if I combine everythingCausality
@Causality I am not talking about IDE, but jar making tool,google itLimey
R
4

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.

Reveille answered 16/1, 2013 at 3:5 Comment(1)
Sorry, I knew that simply combining Jars wouldn't work, per the reasons you provided. So I guess my point was to hopefully get a simple example of code/work/logic that explains how to accomplish what I want in a scenario of your choice - Eclipse, Netbeans, Maven, whatever. So as you suggested using Maven, I didn't know if you could provide some steps to do this. I'll look at the second link (as I do have Maven installed and are using it in a different project, although I'm not the one managing it). So thanks :)Causality
P
-1

From the base of your bin directory, why not try:

jar.exe -cvf cxapplet.jar *

Place your external jar files in the appropriate location in you your bin directory, and manually jar your class files with the external jar files.

Alternatively, see this thread which might provide more information for you.

Postulant answered 16/1, 2013 at 2:24 Comment(3)
"why not try" - because I didn't think of it :) It never crossed my mind, and I didn't know how to use the jar tool effectively, or think to use it on the bin. Also, the only thing in the bin directory is my main Class's compiled code (via its package), so how would I include the things in the lib directory (next to bin), which are the two external Jars, and extract/combine them with the bin directory's contents?Causality
(I'm doing this from memory of something I tried about 4 months ago). Just copy your lib dir into your build dir after building the project. Also, see my editted answer.Postulant
Jeez, I don't know why I didn't think to do that. So when I tried it, it does combine them, but it simply puts the two external Jars into the root of the new Jar...but it seems that what I really need is to extract everything from the external Jars and then zip them all back together. Does that make sense? Netbeans is effectively doing the same thing as what you provided, except also added them to the classpath in the manifest file so that they are recognizable (or however that works).Causality

© 2022 - 2024 — McMap. All rights reserved.