问题
Im unable to run the generated jar file with my spring-boot with jersey project.
exception that i encounter is:
Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 1
Project runs properly when it's done via IDE (running the Main class) or when using spring-boot:run
Here are the details of the current setup:
Packaging:
jar
dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
my jersey configuration (ResourceConfig) is set to scan packages
@Component
public class JerseyConfiguration extends ResourceConfig {
public JerseyConfiguration() {
packages(true, "com.my.base.jaxrs.packages");
}
}
spring-boot-maven-plugin configured as: org.springframework.boot
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
I also did not use the spring-boot-starter-parent but added the spring-boot-dependencies as indicated in the docs.
回答1:
I had this problem, I did not want to complicate things too much so I just registered all my jersey controllers individually.
@Configuration
public class JerseyConfig extends ResourceConfig {
JerseyConfig() {
// my old version that does not play well with spring boot fat jar
/*
packages(
"com.mycompany.api.resources"
);
*/
register(com.mycompany.api.resources.FooController.class);
register(com.mycompany.api.resources.BarController.class);
}
NOTE: I would not recommend this for large projects with many files, it will very quickly become long and unreadable and tedious to maintain.
That said, it is a working solution and you will be able to run your jar with the usual java -jar my-project.jar
command.
回答2:
This is more of a workaround than an actual valid solution to use packages(true, "my.package");
in reference to Anton's answer, i settled with this solution with the limitation that it requires resources with class level @Path or @Provider annotation:
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AnnotationTypeFilter(Path.class));
provider.addIncludeFilter(new AnnotationTypeFilter(Provider.class));
provider.findCandidateComponents("my.package.here").forEach(beanDefinition -> {
try {
LOGGER.info("registering {} to jersey config", beanDefinition.getBeanClassName());
register(Class.forName(beanDefinition.getBeanClassName()));
} catch (ClassNotFoundException e) {
LOGGER.warn("Failed to register: {}", beanDefinition.getBeanClassName());
}
});
回答3:
Alternatively you could do,
@Configuration
public class JerseyConfig extends ResourceConfig {
JerseyConfig() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setResourcePackage("com.mycompany.api.resources");
}
}
来源:https://stackoverflow.com/questions/42218999/unable-to-run-generated-jar-from-spring-boot-jersey