1

I need to be able to allow my maven package to be executed in two contexts.

  1. User needs to execute jar from the command line to generate a licence key from an AWT dialog that appears when the user executes java -jar myjar.jar

  2. myjar needs to also download all its transitive dependencies (in the "normal" maven way) when a client project references myjar as a dependency.

Scenario 1 requires the AWT forms jar to be packaged so that the AWT dialog pops up.
Scenario 2 requires all the other dependencies to be downloaded as the client project builds.

How do I package this to keep it as small as possible?

I've tried the jar-plugin, the shade-plugin and the assembly-plugin independently without much luck.

JAR-PLUGIN:
Placing the forms-1.2.1.jar in the lib/ directory and adding it to the classpath doesn't work because java -jar myjar.jar will not load it at the commandline

SHADE-PLUGIN:
Downloads the internet. How to exclude some dependencies?

ASSEMBLY-PLUGIN:
Downloads the internet. How to exclude some dependencies?

Is there a way to package the transitive dependencies of forms-1.2.1.jar (for scenario 1) but exclude all other dependencies at packaging time so they are downloaded at client project build time (for scenario 2).

Can the jar-plugin or assembly-plugin do this?

Andrew Gray
  • 3,593
  • 3
  • 35
  • 62
  • 1
    don't get 2 use case. you want jar download it's own dependency? embed maven inside it :) – talex Dec 19 '14 at 12:50
  • Use case 2 is automatically handled by Maven assuming your artifact has been properly deployed with a POM file. When the user references your artifact as a dependency, Maven will use the supplied POM to determine which dependencies to resolve. A "jar-with-dependencies" will not be the artifact someone gets when they refer to it in a Maven POM. They will get the normal one, and any dependencies will be resolved using their local repo. The "one-jar" method is purely used for ease of distribution in a non-Maven way. – Ryan J Dec 19 '14 at 22:38
  • @ryan-j I want to distribute myjar via maven central. Thanks for clarifying that one-jar is therefore the incorrect approach. See my edits above. – Andrew Gray Dec 20 '14 at 01:32
  • @Andrew 1) you can't use a classpath with the `java -jar` option because it will be ignored. The proper way to use the jar with the classpath option is to reference the main class directly. That's why it doesn't work for you. 2) I'm not sure why you'd want to exclude anything at package time. You either have the "one jar" method that you can distribute easily, the "normal" way with all dependencies distributed separately and loaded using the classpath, or via Maven, where all dependencies are resolved by Maven and the client project can handle their own build. – Ryan J Dec 20 '14 at 01:54
  • @RyanJ re 2) I'm wanting to exclude dependencies to keep it as small as possible. but if the forms dependency is not present java -jar fails. Hence I am wanting to include the forms dependency related classes only. – Andrew Gray Dec 20 '14 at 02:20
  • @Andrew I think you are missing the point of Maven dependency management, which is why you're having trouble doing what you want. Use of the assembly/jar plugins will allow you to exclude artifacts, but they will not affect the "normal" artifact build, which is what is deployed when you use Maven deploy. – Ryan J Dec 20 '14 at 03:33
  • @Andrew Do you have an example project somewhere? Maybe on Github? It sounds like you are mixing things here. First you have the build time and the usage time by realy end user (not other devs who uses your lib as dependency). – khmarbaise Dec 27 '14 at 10:13

1 Answers1

0

What you think about the following:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <!-- NOTE: We don't need a groupId specification because the group is
             org.apache.maven.plugins ...which is assumed by default.
         -->
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.2</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
        [...]
</project>

That will produce a jar file which contains all dependencies and make it possible to call it from command line, but to get it working correctly you need a supplemental part:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.2</version>
        <configuration>
          [...]
          <archive>
            <manifest>
              <mainClass>org.sample.App</mainClass>
            </manifest>
          </archive>
        </configuration>
        [...]
      </plugin>
      [...]
</project>
khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • Thank you @khmarbaise. I also tried this approach early on. Is there a way to include only forms-1.2.1 for scenario 1 to work and exclude all other dependencies at myjar packaging time so that maven downloads them at client project packaging time? – Andrew Gray Dec 20 '14 at 01:49
  • If you have a special requirement regarding the dependency it's best to create a separate module which contains the appropriate dependencies and than let maven-assembly-plugin do the rest. – khmarbaise Dec 20 '14 at 10:52
  • Are you advocating for a multi maven project in this scenario? If so, does that mean that both modules need to published to Maven Central? – Andrew Gray Dec 26 '14 at 05:34