0

I'm building a java service which has two distribution. Each distribution must be build different (one has a spring-boot embedded jetty server inside, the other not). In both, I created a distribution with dependencies, except one (already achieved). The jar without jetty is build using maven-assembly-plugin (similarly as here Problems running executable jar with dependencies) the other one uses spring-boot-maven-plugin (see http://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html). My issue is the external dependencies.

I want add an additional dependency on runtime, but I DON'T WANT TO US OSGi

In both building process the result is a 'executable' jar, which I can run like this:

java -jar my.jar

But I don't know how to address the additional dependencies. If I run the command above without a the external dependency (lets say external.jar) inside my.jar will fail, even if is in the same folder. I can make it work for the distribution without jetty like this:

java -classpath "./*" my.main.App

But this doesn't work for my-with-jetty.jar. I also try to run:

java -classpath "./*" -jar my-with-jetty.jar

This simply doesn't work.

So my question are:

is it possible to pack a jar with almost all the dependencies for both cases?

is it possible to pack the jar as runnable jar such that it not necessary to provide the main class?

of course if yes, how? I would like to run both distribution in the same manner.

I want similar behavior:

java -cp "./*" java -jar my.jar conf.cfg

and

java -cp "./*" java -jar my-rest.jar conf.cfg

Thank you.

Community
  • 1
  • 1
ender.an27
  • 703
  • 1
  • 13
  • 35

1 Answers1

0

You need at least 3 maven projects all under the same parent so they get built together and have the same version. All your code will be in the shared project, this will be included in both runnable jar projects. Each runnable jar project will be build differently.

Your parent pom will be something like :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>foo.bar</groupId>
  <artifactId>parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>shared-jar</module>
    <module>spring-boot-jar</module>
    <module>jetty-jar</module>
  </modules>

</project>

Your shared-jar project will have all the shared code

Your spring-boot-jar will look like :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>foo.bar</groupId>
        <artifactId>parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>spring-boot-jar</artifactId>
    <packaging>jar</packaging>

    <dependencies>
       <dependency>
          <groupId>foo.bar</groupId>
          <artifactId>shared-jar</artifactId>
          <version>${project.version}</version>
       </dependency>
        .... you will need to add all the spring boot dependencies with versions
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Your jetty-jar will be built using the

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <parent>
            <groupId>foo.bar</groupId>
            <artifactId>parent</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <artifactId>jetty-jar</artifactId>
        <packaging>jar</packaging>

        <dependencies>
           <dependency>
              <groupId>foo.bar</groupId>
              <artifactId>shared-jar</artifactId>
              <version>${project.version}</version>
           </dependency>
            .... other dependencies
        </dependencies>

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <manifestEntries>
                                        <!-- <Main-Class>foo.bar.Application</Main-Class> -->
                                    </manifestEntries>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

    </project>
Essex Boy
  • 7,565
  • 2
  • 21
  • 24
  • Sorry I don't understand the question, you have 2 jars one is run as spring boot, the other not. How is the non spring-boot jar to be run? – Essex Boy Mar 29 '17 at 10:20
  • One provides an MQTT API, the other an REST API. So actually both can be started by `java -jar my.jar` – ender.an27 Mar 29 '17 at 11:37
  • So they do not have the same main class? You can either have a different main class, or use spring profiles to expose different bits in the same jar based on the -Dspring.profiles.active flag. – Essex Boy Mar 29 '17 at 11:46
  • Each jar (my.jar and my-rest.jar) have different main class but just one per jar. Can be started as `java -jar my.jar` && `java -jar my-rest.jar`.But I want both to load an additional dependency `extern.jar` – ender.an27 Mar 29 '17 at 11:54
  • So you have a shared jar, and 2 jars need to be built with different main classes, but both share the common jar? Both jars need to be run from the command line? Both jars need to be built in the same maven project? – Essex Boy Mar 29 '17 at 11:59
  • Finally do you make extern.jar or does that come from maven repo? – Essex Boy Mar 29 '17 at 12:00
  • no it is not shared. It is possible to have copies. They both use the same kind but not the same one. Actually, both have almost the same dependency structure, but one starts a HTTP server the other not. So both needs to load additional libs if needed. – ender.an27 Mar 29 '17 at 12:08
  • about the repo, I can make both. I build and deploy it in a remote repo. – ender.an27 Mar 29 '17 at 12:10
  • Look at the answer now, you have a parent and 3 jars, one shared, and 2 runnable. – Essex Boy Mar 29 '17 at 12:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139365/discussion-between-ender-an27-and-essex-boy). – ender.an27 Mar 29 '17 at 12:46