Spring Boot应用在Eclipse外启动无法读取application.properties
Spring Boot Fat Jar启动时@Value注解无法解析配置项问题
本地用Eclipse(非STS)以普通Java应用启动Spring Boot 2.7.12项目完全正常,无额外JVM或应用参数。但通过Maven assembly插件构建fat jar后,执行java -jar myJar.jar启动时,Spring无法填充@Value注解,抛出配置占位符无法解析的异常。
报错信息
java -Xmx2g -jar myJar.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.12) Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hsqlServer' defined in class path resource [org/pepito/myjar/config/SpringConfig.class]: Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'hsqldb.server.database' in value "${hsqldb.server.database}" ... Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'hsqldb.server.database' in value "${hsqldb.server.database}" ...
排查细节
- 配置项
hsqldb.server.database已定义在默认的application.properties中,且该文件已正确打包到fat jar的classpath:/application.properties路径下 - 尝试添加启动参数
--spring.config.location="classpath:application.properties"强制指定配置文件,问题依旧 - 开发环境:MacOS M2(Java 8),运行环境:32位Linux Mint 19(Java 8)
相关代码与配置
Maven构建配置
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.7.12</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.9.0</version> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <configuration> <finalName>myJar</finalName> <archive> <manifest> <mainClass> org.pepito.myjar.SpringBootTgApplication </mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <appendAssemblyId>false</appendAssemblyId> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
主类代码
@SpringBootApplication public class SpringBootTgApplication { public static void main(String[] args) { SpringApplication.run(SpringBootTgApplication.class, args); try { new TelegramBotsApi(DefaultBotSession.class); } catch (TelegramApiException e) { throw new RuntimeException(e); } } }
Bean配置类
@Configuration @EnableAutoConfiguration public class SpringConfig { @Bean(initMethod = "start", destroyMethod = "stop") public Server hsqlServer(@Value("${hsqldb.server.database}") String dbType, @Value("${hsqldb.server.dbname}") String dbName, @Value("${hsqldb.server.no_system_exit}") Boolean noSystemExit, @Value("${hsqldb.server.port}") Integer serverPort, @Value("${hsqldb.server.remote_open}") Boolean remoteOpen) throws IOException, AclFormatException { Server bean = new Server(); HsqlProperties props = new HsqlProperties(); props.setProperty("server.database.0", dbType); props.setProperty("server.dbname.0", dbName); props.setProperty("server.no_system_exit", noSystemExit); props.setProperty("server.port", serverPort); props.setProperty("server.remote_open", remoteOpen); bean.setProperties(props); return bean; } @Bean @DependsOn("hsqlServer") public DataSource getDataSource(@Value("${hsqldb.datasource.driver-class-name}") String driverClassName, @Value("${hsqldb.datasource.url}") String url, @Value("${hsqldb.datasource.username}") String username, @Value("${hsqldb.datasource.password}") String password) { DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create(); dataSourceBuilder.driverClassName(driverClassName); dataSourceBuilder.url(url); dataSourceBuilder.username(username); dataSourceBuilder.password(password); return dataSourceBuilder.build(); } }
application.properties内容
server.port=28000 BOT_TOKEN=<token> BOT_NAME=<value> CCAA=<value> hsqldb.server.database=file:<file> hsqldb.server.dbname=<db name> hsqldb.server.no_system_exit=true hsqldb.server.port=9001 hsqldb.server.remote_open=true hsqldb.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver hsqldb.datasource.url=jdbc:hsqldb:hsql://localhost/<db name> hsqldb.datasource.username=<user> hsqldb.datasource.password=<pass> spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update logging.level.root=INFO logging.level.org.pepito=TRACE
问题更新
改用Maven shade插件构建fat jar后,应用可正常启动,@Value注解能正确解析配置项,推测问题根源在于assembly插件与Spring Boot的fat jar构建逻辑不兼容。
内容的提问来源于stack exchange,提问作者Cheloute
相关产品推荐
相关产品推荐

