Spring Boot application runs fine with spring-boot:run but not with java -jar
See original GitHub issueSpring Boot version: 1.5.3 Java: 1.8 Maven: 3.5.0 OS: Ubuntu 16.10 x64
I have a Spring Boot project here: https://github.com/aifa-gov-it/invoices-processor
I have multiple unit and integration test, marked with @SpringBootTest that run fine, as you can see from the Travis CI build logs (example: https://travis-ci.org/aifa-gov-it/invoices-processor/builds/236038253).
If I build the project with mvn clean install -s settings.xml and then run the jar with java -jar target/database-uploader-exec.jar (the -exec qualifier has been added with the qualifier configuration option of the spring-boot-maven-plugin, I get a:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'java.util.Set<it.gov.aifa.invoice_processor.service.InvoiceMappingToEntityConverter<it.gov.aifa.invoice_processor.mapping.InvoiceMapping<java.lang.String>, it.gov.aifa.invoice_processor.entity.invoice.Invoice>>' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.hibernate.validator.constraints.NotEmpty(message={org.hibernate.validator.constraints.NotEmpty.message}, payload=[], groups=[])}
The jar runs fine with the spring-boot:run goal and so do unit and integration tests, so I’m suspecting an issue with the executable JAR. I also tried to add the executable configuration option but it changed nothing.
Shouldn’t the spring-boot-maven-plugin produce a bootable JAR out-of-the-box?
Relevant bits:
pom.xml:
<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>it.gov.aifa</groupId>
<artifactId>database-uploader</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<developers>
<developer>
<id>ferrarimarco</id>
<email>ferrari.marco@gmail.com</email>
<name>Marco Ferrari</name>
<organization>Italian Medicines Agency - AIFA</organization>
<organizationUrl>http://www.aifa.gov.it/</organizationUrl>
</developer>
</developers>
<inceptionYear>2017</inceptionYear>
<organization>
<name>Italian Medicines Agency - AIFA</name>
<url>http://www.aifa.gov.it/</url>
</organization>
<properties>
<!-- Environment properties -->
<java.version>1.8</java.version>
<maven-required.version>3.3.9</maven-required.version>
<project.resources.sourceEncoding>UTF-8</project.resources.sourceEncoding>
<!-- Dependencies (keep this alphabetically ordered) -->
<commons-io.version>2.5</commons-io.version>
<commons-lang3.version>3.5</commons-lang3.version>
<java-ee-api.version>7.0</java-ee-api.version>
<liquibase-hibernate5.version>3.6</liquibase-hibernate5.version>
<mockito-all.version>2.0.2-beta</mockito-all.version>
<ojdbc.version>12.2.0.1</ojdbc.version>
<spring-boot.version>${project.parent.version}</spring-boot.version>
<sysout-over-slf4j.version>1.0.2</sysout-over-slf4j.version>
<testng.version>6.11</testng.version>
<!-- Plugins (keep this alphabetically ordered) -->
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
<jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version>
<maven-project-info-reports-plugin.version>2.9</maven-project-info-reports-plugin.version>
<maven-release-plugin.version>2.5.3</maven-release-plugin.version>
<maven-surefire-report-plugin.version>${maven-surefire-plugin.version}</maven-surefire-report-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>${ojdbc.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>uk.org.lidalia</groupId>
<artifactId>sysout-over-slf4j</artifactId>
<version>${sysout-over-slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito-all.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>${maven-required.version}</version>
</requireMavenVersion>
<requireJavaVersion>
<version>${java.version}</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<!-- Skips tests if the value of skip.unit.tests property is true -->
<skipTests>${skipTests}</skipTests>
<skipITs>${skipTests}</skipITs>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>generate-test-jar</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>${maven-release-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Skips unit tests if the value of skip.unit.tests property is true -->
<skipTests>${skipTests}</skipTests>
<workingDirectory>${project.build.directory}</workingDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>${coveralls-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<haltOnFailure>false</haltOnFailure>
<rules>
<!-- implementation is needed only for Maven 2 -->
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<!-- implementation is needed only for Maven 2 -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
<configuration>
<changeLogFile>src/main/resources/db/changelog/db.changelog-master.yaml</changeLogFile>
<diffChangeLogFile>src/main/resources/db/changelog/db.changelog-${project.version}.yaml</diffChangeLogFile>
<driver>org.h2.Driver</driver>
<outputFileEncoding>${project.resources.sourceEncoding}</outputFileEncoding>
<referenceUrl>hibernate:spring:it.gov.aifa.invoice_processor.entity?dialect=org.hibernate.dialect.Oracle12cDialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy</referenceUrl>
<url>jdbc:h2:mem:testdb</url>
<username>sa</username>
<password>sa</password>
</configuration>
<dependencies>
<dependency>
<groupId>org.liquibase.ext</groupId>
<artifactId>liquibase-hibernate5</artifactId>
<version>${liquibase-hibernate5.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${maven-surefire-report-plugin.version}</version>
<reportSets>
<reportSet>
<id>unit-tests</id>
<reports>
<report>report-only</report>
</reports>
</reportSet>
<reportSet>
<id>integration-tests</id>
<reports>
<report>failsafe-report-only</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<reportSets>
<reportSet>
<id>jacoco-unit-tests</id>
<reports>
<report>report</report>
</reports>
</reportSet>
<reportSet>
<id>jacoco-integration-tests</id>
<reports>
<report>report-integration</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${maven-project-info-reports-plugin.version}</version>
</plugin>
</plugins>
</reporting>
</project>
Issue Analytics
- State:
- Created 6 years ago
- Comments:9 (5 by maintainers)

Top Related StackOverflow Question
This is quite a complicated one, but doesn’t actually have anything to do with Spring Boot. The reason for the different behaviour isn’t due to a difference in
mvn spring-boot:runvsjava -jarspecifically, but due to a difference in the ordering of the class path. In both cases it’s governed by Maven.We can conclude from
mvn spring-boot:runworking andjava -jarfailing that Maven uses a different ordering for the classes when running and when packing them in a jar file. It’s also interesting that the jar that I built (which works) has its contents in a different order to those in the jar that you built (which doesn’t). From that, we can conclude that ordering of classes in a Maven-built jar may vary as well.The ordering of the class path is important as it has an effect on when the beans in your application are created. When Spring Framework is looking at a bean instance it has more information available to it about the bean’s type than it does when it’s only looking at a bean definition. The injection that’s failing is reliant upon the resolution of a fairly complex generic type signature and this only succeeds when the
Invoice1_2MappingToEntityConverterImplbean has been instantiated and the Framework can examine an instance of this bean rather than just its definition.In the failing case, the injection of
Set<InvoiceMappingToEntityConverter<InvoiceMapping<String>, Invoice>>intoInvoiceMappingProcessorfails because it is happening beforeInvoice1_2MappingToEntityConverterImplhas been instantiated. In the successful case, the injection succeeds asInvoice1_2MappingToEntityConverterImplhas already been instantiated.In the case of the two different jars, this difference in ordering is due to the different ordering of the entries in the jar:
vs
If I rename
InvoiceMappingProcessortoAnInvoiceMappingProcessorI can reproduce the injection failure in Eclipse as it causes the processor bean to be created before the converter bean as the processor then appears first on the class path.There may be an improvement that could be made in Spring Framework here, but I really can’t tell for certain. If you’d like to pursue that, I would recommend stripping your application down as much as possible to a bare minimum that reproduces the problem and then opening a Spring Framework JIRA.
@wilkinsona I solved the problem. I use jsf ( i knew jsf is stateful but customer’s requirement ) spring boot for my project. I add folder “META-INF/resources” under “src/main/resources” in order to act like “webapp” like normal maven web project. When i run it in “mvn spring-boot:run” or run project in IDE, it works perfectly but when i build it to jar file to distribute to EC2. It not read “faces-config.xml” under “META-INF/resources/WEB-INF”. Thus resource-bundle inside faces-config.xml was not setup. So i move it in “META-INF” forlder and it worked. Any one got problem ?? please tell me why
NOT Work src/main/resource ---------------------META-INF -------------------------resources -----------------------------WEB-INFO ---------------------------------faces-config.xml
Work src/main/resource ---------------------META-INF -------------------------faces-config.xml -------------------------resources -----------------------------WEB-INFO