0

I am developing a project, which contains a ui-module, which provides a Web-UI using Spring. The project hast the following structure:

project
 - ui
   - pom.xml
   - src/main/java
 - main
   - pom.xml
   - src/main/java
 - core
   - pom.xml
   - src/main/java
 - pom.xml

Only the ui module has the dependency to spring (and the others should never know about spring, to decouple it from the rest of the project). Its pom.xml file looks like this:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.3.RELEASE</version>
    <relativePath/>
</parent>

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

<dependencies>
    <dependency>
        <groupId>my.id</groupId>
        <artifactId>core</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

The root pom looks like this:

<modules>
    <module>ui</module>
    <module>core</module>
    <module>main</module>
</modules>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
            <version>3.7.0</version>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <skipAssembly>false</skipAssembly>
                <archive>
                    <manifest>
                        <mainClass>my.id.main.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>my.id.main.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>my.id</groupId>
        <artifactId>core</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>my.id</groupId>
        <artifactId>ui</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>my.id</groupId>
        <artifactId>main</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

The Problem

I was trying to create an executable jar, to deploy this application on a server. I ran:

mvn clean compile package verify install

To clarify, i only use this unorthodox statement, because everything else does not work. Calling mvn clean install will result in the same jar as before.

Calling mvn clean compile install will result in an Maven error, stating the "repackage failed".

Only after calling mvn clean compile package install will result in a totally new jar.

This error is work in progress by me and not part of the Question.

The resulting jar will be executable and the Spring-boot output will be shown, but after a short while, the following exception will be thrown:

Exception in thread "pool-1-thread-3" java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.

So i googled for a while and found the (possible) solution to manually create the src/main/resources/META-INF/spring.factories file. The resulted in Exceptions, which could be removed by removing the faulty lines of in the spring.factories file. However, afterwards i got the following exception:

org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.

Is it at all possible, to create an executable jar whith such a project structure?

I also tried to give the spring parent to the root pom.xml. This however did not bring the result i needed. The result was the same as before.


edit

I also tried to package the jar from the main module. This raises the first problem, that i would have to know the ui from within the main (which originally was not what i wanted. The main module should only have a dependency to Guice and request implementations of some interfaces, without knowing the modules). After adding the dependency, i tried to create an executable jar anyways, but got the same result.


edit2

This question is not concerned about how can i Compile a multi-module Maven project at once, but about the reason the resulting jar-with-dependencies can be run, but as soon as Spring should start (after the Spring-boot output is displayed), an IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories is thrown and how i can fix this issue.

I found (as stated within the question) a possible solution, which did not work for me.

Thorben Kuck
  • 1,092
  • 12
  • 25
  • 2
    Calling `mvn clean compile package verify install` shows that you haven't understood the maven build life cycle. You are repeating several things three or four times...usually you only need `mvn clean verify`...I recommend to read about the [build life cycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html). – khmarbaise Sep 01 '18 at 19:40
  • Maven is *highly opinionated* and works best when you use it the way it is intended to be used. Effort is proportional to how much you stick to the *standard* way of doing things, and if you are not willing to do this, you probably picked the wrong tool. –  Sep 02 '18 at 16:11
  • What is going on? "mvn clean install" will result in the same jar as before (no change). "mvn clean compile install" will result in a repackage failed error. Only "mvn clean compile package verify" will result in a new jar being created. This might be not what you are supposed to do, but it is the only thing that works for me at the moment. – Thorben Kuck Sep 02 '18 at 16:17

0 Answers0