更新:如果我只是将extension
项目添加为master
的依赖项,则会出现同样的错误。
更新2 :我创建了一个Github仓库来重现错误:https://github.com/papagno/spring-factories-test
我正在尝试使用Spring Boot和spring.factories文件。所以我创建了两个简单的项目:
<layout>ZIP</layout>
作为spring-boot-maven-plugin
的配置。扩展
spring-boot-starter
作为依赖项。resources/META-INF
中的以下spring.factories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
my.package.extension.ExtensionAutoConfiguration
它还包含仅my.package.ExtensionAutoConfiguration
注释的@Configuration
类,并声明@Bean
:
package my.package.extension;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ExtensionAutoConfiguration
{
@Bean
ExtensionService extensionService()
{
return new ExtensionService();
}
}
我使用maven编译两个项目,将两个jar放在同一个文件夹中,然后使用以下命令运行master:
java -Dloader.path=. -jar master-0.0.1-SNAPSHOT.jar
spring.factories
已被识别,但当Spring尝试实例化我的自动配置类时,我得到该类的FileNotFoundException
。
这是堆栈跟踪:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [my.package.master.MasterApplication]; nested exception is java.lang.IllegalStateException: java.io.FileNotFoundException: class path resource [my/package/extension/ExtensionAutoConfiguration.class] cannot be opened because it does not exist
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:482) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:184) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:270) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) [spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at my.package.master.MasterApplication.main(MasterApplication.java:10) [classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [master-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [master-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [master-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:521) [master-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: java.lang.IllegalStateException: java.io.FileNotFoundException: class path resource [my/package/extension/ExtensionAutoConfiguration.class] cannot be opened because it does not exist
at org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector.selectImports(EnableAutoConfigurationImportSelector.java:94) ~[spring-boot-autoconfigure-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:474) ~[spring-context-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
... 22 common frames omitted
Caused by: java.io.FileNotFoundException: class path resource [my/package/extension/ExtensionAutoConfiguration.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172) ~[spring-core-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50) ~[spring-core-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:98) ~[spring-core-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:89) ~[spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:76) ~[spring-boot-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:93) ~[spring-core-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClasses.<init>(AutoConfigurationSorter.java:110) ~[spring-boot-autoconfigure-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.autoconfigure.AutoConfigurationSorter.getInPriorityOrder(AutoConfigurationSorter.java:54) ~[spring-boot-autoconfigure-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector.sort(EnableAutoConfigurationImportSelector.java:193) ~[spring-boot-autoconfigure-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
at org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector.selectImports(EnableAutoConfigurationImportSelector.java:89) ~[spring-boot-autoconfigure-1.4.3.RELEASE.jar!/:1.4.3.RELEASE]
... 23 common frames omitted
我做错了吗?我该怎么做才能了解发生了什么?谢谢。
答案 0 :(得分:1)
您的扩展程序不能是Spring Boot应用程序(没有父spring-boot-starter-parent
)。
当您将spring-boot-starter-parent声明为父级时,生成的jar将使用Sring-Boot风格重新打包,并且这些类不在预期的文件夹中。如果打开extension-0.0.1-SNAPSHOT.jar
,则类在BOOT-INF / classes中,因此当jar用作库时,不会找到任何类。这些类需要位于jar内部的根目录。
对扩展项目使用以下pom.xml
:
<?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>com.example</groupId>
<artifactId>extension</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>extension</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
在上面的代码示例中,我仍然将spring-boot-starter-parent声明为dependencyManagement - import
,因此继承了版本声明。但是,spring-boot-maven-plugin将不会被执行,jar将不会被重新打包,它将可用作库。