Spring Boot MVC Multi-Module Executeable jar

13,070

Finally I found solution. The magic keyword is repackage, see link http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/usage.html

So I only need spring-boot-maven-plugin in my web module configured with repackage goal:

<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
            <execution>
                <goals>
                    <goal>repackage</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

Then all dependencies are packed in executeable jar file and is startable from console.

I hope it helps for people who face same issue.

Share:
13,070

Related videos on Youtube

Michael Hegner
Author by

Michael Hegner

Updated on June 05, 2022

Comments

  • Michael Hegner
    Michael Hegner almost 2 years

    I have a multimodule project, build with spring boot 1.1.7

    The structure is

    + parent
        + import
            + web
            + backend
    

    My Parent Module will include kind of microservices, what I want to manage from my parent (dependencies what all use) and so on. In import/backend there is my batch business logic, in web there is a mvc application, from where I can start batch job.

    In Eclipse everything works fine for me, I can start the application from the Application.java file and application works.

    Now I wanted to execute that application by executing executable jar file, but I get following error message when try starting from console.

    java -jar application.jar
    Kein Hauptmanifestattribut in application.jar
    

    The jar is very small only 5kb, I didn't find any jars of 3 party dependencies in jar package.

    The Pom of Web-Module is like follows:

        <project>
    
            <modelVersion>4.0.0</modelVersion>
    
            <parent>
                <groupId>at.company.bbsng</groupId>
                <artifactId>bbsng-import</artifactId>
                <version>0.1.0-SNAPSHOT</version>
            </parent>
    
            <artifactId>bbsng-import-web</artifactId>
            <name>bbsng-import-web</name>
            <packaging>jar</packaging>
    
            <properties>
                <start-class>at.company.bbsng.dataimport.Application</start-class>
            </properties>
    
    
            <dependencies>
    
                 <!-- APPLICATION -->
                <dependency>
                    <groupId>at.company.bbsng</groupId>
                    <artifactId>bbsng-import-backend</artifactId>
                    <version>${parent.version}</version>
                </dependency>
    
                <!-- SPRING ... -->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <exclusions>
                        <exclusion>
                            <artifactId>spring-boot-starter-logging</artifactId>
                            <groupId>org.springframework.boot</groupId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-log4j</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                    <scope>test</scope>
                </dependency>
    
                ...
    
    
            </dependencies>
    
    
    
            <build>
    
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                    </plugin>
                </plugins>
    
            </build>
    
    </project>
    

    Pom of Import Module is:

    <project>
    
        <parent>
            <groupId>at.company.bbsng</groupId>
            <artifactId>bbsng</artifactId>
            <version>0.1.0-SNAPSHOT</version>
        </parent>
    
        <artifactId>bbsng-import</artifactId>
        <name>bbsng-import</name>
        <packaging>pom</packaging>
    
        <modules>
            <module>backend</module>
            <module>web</module>
        </modules>
    
    </project>
    

    And Pom of Parent is:

    <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>at.company.bbsng</groupId>
        <artifactId>bbsng</artifactId>
        <version>0.1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
        <name>bbsng</name>
        <description>BBS Next Generation Application Prototype</description>
    
        <properties>
            <java-version>1.8</java-version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <org.springframework.boot-version>1.1.7.RELEASE</org.springframework.boot-version>
        </properties>
    
        <modules>
            <!-- <module>backend</module> -->
            <!-- <module>business</module> -->
            <module>import</module>
            <!-- <module>infra</module> -->
            <!-- <module>log</module> -->
            <!-- <module>rest</module> -->
        </modules>
    
        <dependencyManagement>
            <dependencies>
    
                <!-- SPRING-BOOT ... -->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <type>pom</type>
                    <version>${org.springframework.boot-version}</version>
                    <scope>import</scope>
                </dependency>
    
                <!-- JAVAX ... -->
                <dependency>
                    <groupId>javax.validation</groupId>
                    <artifactId>validation-api</artifactId>
                    <version>1.1.0.Final</version>
                </dependency>
    
                <!-- COMMONS ... -->
    
                ...
    
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-release-plugin</artifactId>
                    <version>2.5</version>
                    <configuration>
                        <tagBase>
                            svn://svn.int.company.at/stmlf-repository/prototype/bbsng/tags
                        </tagBase>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>${java-version}</source>
                        <target>${java-version}</target>
                    </configuration>
                </plugin>
            </plugins>
    
        </build>
    
        <profiles>
            <profile>
                <id>external</id>
                <build>
                    <resources>
                        <resource>
                            <directory>src/main/resources</directory>
                            <excludes>
                                <exclude>**/*custom*</exclude>
                                <exclude>**/custom/*</exclude>
                            </excludes>
                        </resource>
                    </resources>
                </build>
            </profile>
        </profiles>    
    
    </project>
    

    If you need further information please ask. Hope you can help me.

    Thank you very much.

    • M. Deinum
      M. Deinum over 9 years
      The problem is that your runnable application class should be in the main project not in a sub/imported project. It might work if you explicitly define the main class for the manifest when the jar is being build.
    • Michael Hegner
      Michael Hegner over 9 years
      Thank you for your answer, it was correct, that properties start-class were not set correctly, I fixed that. But it didnt help me with my problem. One of the strange problems are, that no dependencies configured in maven are in my jar-file. They are all missing, included my backend module is not in my jar what I picked up from my web module. That results my jar has size of 5KB.
    • Serge Ballesta
      Serge Ballesta over 9 years
      What is the pom for bbsng-import-backend ?
    • Michael Hegner
      Michael Hegner over 9 years
      Thank you all, I found solution and edited my post above.
  • xenteros
    xenteros about 7 years
    Could you explain, why it should be in one of submodules? Not in all or in the parent?
  • xenteros
    xenteros about 7 years
    Anyway, I had 4 modules and 1 parent and adding the above to the module in which there was a main method solved the problem.
  • Michael Hegner
    Michael Hegner about 7 years
    I put it in my web module, because there my executable jar will be build. I guess at least you need it there where you get your final jar you want to execute.
  • Jaydatt
    Jaydatt about 6 years
    Hi Michael, I agree that your solution and should solve the problem. I do have exactly same structure. But still its not working for me. The only difference I have is : my spring- boot-starter-parent is 1.5.10.RELEASE and the modules on which my web modules is dependent on has the jar packaging. So, the problem is my executable jar does not include classes from my dependent module. I am pretty much convinced that your solution should work but some how its not working in my case. please let me know if you have any thoughts on this.
  • Michael Hegner
    Michael Hegner about 6 years
    Hi Jaydatt, you have a GIT Repository where I can check out your application?