我在注入带有@Inject
或@Autowired
注释的bean时遇到问题:这在一个名为MultitenantConfiguration
的类中发生:在部署期间,我的Tomcat 8挂起并停止它!只有当应用程序在tomcat上展开时才会发生这种情况,而不是在pom packaging = jar时(所以它作为独立的应用程序运行,因为它是Spring启动应用程序)。注意FileProperties
道具仍然null
我得到NullPointerException
符合代码files = Paths.get(props.getTenantsFilePath()).toFile().listFiles();
.. beacuse propr是null
..
为什么?我能做什么..这些是我的代码行:
的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>com.cadit</groupId>
<artifactId>xxx</artifactId>
<version>1.0</version>
<!-- <packaging>jar</packaging> -->
<packaging>war</packaging>
<name>soci-af-import</name>
<url>http://maven.apache.org</url>
<properties>
<start-class>com.cadit.web.WebApplicationAware</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<camel.version>2.18.1</camel.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</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-test</artifactId>
<scope>test</scope>
</dependency>
<!-- altre dipendenze non spring -->
<!-- CDI API -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<!-- camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot</artifactId>
<version>${camel.version}</version> <!-- use the same version as your Camel core version -->
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-swagger-java-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-servlet-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-csv</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2</artifactId>
<version>${camel.version}</version>
</dependency>
<!-- fine camel -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
<scope>runtime</scope>
</dependency>
<!-- end -->
<!-- dipendenze logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
<!-- fine dip logback -->
</dependencies>
<build>
<!-- commentato perchè viene usato SpringBootServletInitializer -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- <plugin> -->
<!-- <groupId>org.apache.maven.plugins</groupId> -->
<!-- <artifactId>maven-war-plugin</artifactId> -->
<!-- <version>3.0.0</version> -->
<!-- <configuration> -->
<!-- <warName>AfSociImporterRest</warName> -->
<!-- </configuration> -->
<!-- </plugin> -->
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
在网络包中:
@Configuration
@SpringBootApplication
@ComponentScan(basePackages={"com.cadit.multitenant","com.cadit.dao", "com.cadit.entities", "com.cadit.camel"})
@EnableJpaRepositories(basePackages={"com.cadit.dao"})
@EntityScan(basePackages="com.cadit.entities")
@Import(value={FileProperties.class, CamelContextConfVB.class, CamelContextConfS2.class, CamelContextConfRestServices.class})
public class WebApplicationAware extends SpringBootServletInitializer{
private static Class<WebApplicationAware> applicationClass = WebApplicationAware.class;
static final Logger logger = LoggerFactory.getLogger(WebApplicationAware.class);
public static void main(String[] args) {
String pathconf = null;
String path_properties=null;
if (args.length > 0){
path_properties = args[0];
}
if (path_properties == null) logger.error("Manca l'argomento relativo al path assoluto al file di configurazione app.properties!");
if (pathconf == null) pathconf = "application.properties";
System.setProperty("properties.url", pathconf);
System.setProperty("path.properties", path_properties);
//logger.info("** " + System.getenv("path.properties"));
//logger.info("** " + System.getProperty("properties.url"));
//logger.info("** " + System.getProperty("path.properties"));
logger.info("** Registered default application.properties");
if (System.getProperty("path.properties")!= null) {
logger.info("** Registered app.properties from location " + System.getProperty("path.properties"));
}
SpringApplication.run(applicationClass, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
@Bean
public ServletRegistrationBean camelServletRegistrationBean() {
ServletRegistrationBean registration = new ServletRegistrationBean(new CamelHttpTransportServlet(), "/afsiss/*");
registration.setName("CamelServlet");
logger.info("** CamelServlet initialized..");
TenantContext.setCurrentTenant("tenant_1");
return registration;
}
}
在multitenant包中(道具为空!):
@Configuration
public class MultitenantConfiguration {
@Autowired
private DataSourceProperties properties;
@Inject
FileProperties props;
/**
* Defines the data source for the application
* @return
*/
@Bean
@ConfigurationProperties(
prefix = "spring.datasource"
)
public DataSource dataSource() {
//se sono in un jar ed esternamente al jar o nel jar stesso il path tenants esiste
File folderTenatsConf = Paths.get("tenants").toFile();
File[] files =null;
if (folderTenatsConf.exists()){
files = Paths.get("tenants").toFile().listFiles();
}//se sono in una application server come Tomcat (war)..
else {
files = Paths.get(props.getTenantsFilePath()).toFile().listFiles();
}
Map<Object,Object> resolvedDataSources = new HashMap<>();
for(File propertyFile : files) {
Properties tenantProperties = new Properties();
DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader());
try {
tenantProperties.load(new FileInputStream(propertyFile));
String tenantId = tenantProperties.getProperty("name");
dataSourceBuilder.driverClassName(properties.getDriverClassName())
.url(tenantProperties.getProperty("datasource.url"))
.username(tenantProperties.getProperty("datasource.username"))
.password(tenantProperties.getProperty("datasource.password"));
if(properties.getType() != null) {
dataSourceBuilder.type(properties.getType());
}
resolvedDataSources.put(tenantId, dataSourceBuilder.build());
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
// Create the final multi-tenant source.
// It needs a default database to connect to.
// Make sure that the default database is actually an empty tenant database.
// Don't use that for a regular tenant if you want things to be safe!
MultitenantDataSource dataSource = new MultitenantDataSource();
dataSource.setDefaultTargetDataSource(defaultDataSource());
dataSource.setTargetDataSources(resolvedDataSources);
// Call this to finalize the initialization of the data source.
dataSource.afterPropertiesSet();
return dataSource;
}
/**
* Creates the default data source for the application
* @return
*/
private DataSource defaultDataSource() {
DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader())
.driverClassName(properties.getDriverClassName())
.url(properties.getUrl())
.username(properties.getUsername())
.password(properties.getPassword());
if(properties.getType() != null) {
dataSourceBuilder.type(properties.getType());
}
return dataSourceBuilder.build();
}
}
包骆驼:
@Configuration
@PropertySource("file:${path.properties}/app.properties")
@ConfigurationProperties(prefix="multitenancy")
public class FileProperties {
private List<DirProps> dir =new ArrayList<DirProps>();
private String tenantsFilePath;
/**
* lista delle proprietà relative alle directories di ogni società
* @return
*/
public List<DirProps> getDir() {
return dir;
}
public void setDir(List<DirProps> dir) {
this.dir = dir;
}
public String getTenantsFilePath() {
return tenantsFilePath;
}
public void setTenantsFilePath(String tenantsFilePath) {
this.tenantsFilePath = tenantsFilePath;
}
public static class DirProps{
private String tenant; //nome del tenant della società
private String root; //root della societa
private String in; //sottocartella della root dove vanno i file di input
private String out; //sottocartella della root dove vanno i file di out, quelli elaborati
private String refused;//sottocartella della root dove vanno i file di out che non sono stati elaborati perchè errati
private boolean enabled = true; //di default la societa è abilitata
public String getTenant() {
return tenant;
}
public void setTenant(String tenant) {
this.tenant = tenant;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public String getIn() {
return in;
}
public void setIn(String in) {
this.in = in;
}
public String getOut() {
return out;
}
public void setOut(String out) {
this.out = out;
}
public String getRefused() {
return refused;
}
public void setRefused(String refused) {
this.refused = refused;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}
这是我的app.properties(在C:/ Progetti / soci-af-import2 / config中):
multitenancy.tenantsFilePath= C:/Progetti/tenants/
#tenant_1.properties
#tenant di riferimento
multitenancy.dir[0].tenant = tenant_1
multitenancy.dir[0].root = C:/Progetti/
multitenancy.dir[0].in = IN
multitenancy.dir[0].out = ../OUT
#VB\REFUSED IDEM SOPRA
multitenancy.dir[0].refused = ../REFUSED
multitenancy.dir[0].enabled = true
这就是app.properties以及我的webapp如何部署的方式(Tomcat / conf / Server.xml):
<Service name="siss-af-import2Service">
<Connector port="8090"/>
<Engine defaultHost="localhost" name="siss-af-import2Engine">
<Host name="localhost" appBase="C:/Progetticcc/target">
<Context docBase="soci-af-import-1.0" path="afsiss">
<Parameter name="path.properties" value="C:/Progetti/soci-af-import2/config"/>
</Context>
</Host>
</Engine>
</Service>
这是tomcat stackTrace:
Sep 04, 2017 2:42:59 PM org.apache.jasper.servlet.TldScanner scanJars
[com/cadit/multitenant/MultitenantConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException
04/09/2017 14:43:08.894 INFO [localhost-startStop-1] - org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer:
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
04/09/2017 14:43:08.912 ERROR [localhost-startStop-1] - org.springframework.boot.SpringApplication: Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/cadit/multitenant/MultitenantConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5244)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/cadit/multitenant/MultitenantConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 37 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 50 common frames omitted
Caused by: java.lang.NullPointerException: null
at com.cadit.multitenant.MultitenantConfiguration.dataSource(MultitenantConfiguration.java:62)
at com.cadit.multitenant.MultitenantConfiguration$$EnhancerBySpringCGLIB$$321a1e90.CGLIB$dataSource$0(<generated>)
at com.cadit.multitenant.MultitenantConfiguration$$EnhancerBySpringCGLIB$$321a1e90$$FastClassBySpringCGLIB$$e04a7d0b.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at com.cadit.multitenant.MultitenantConfiguration$$EnhancerBySpringCGLIB$$321a1e90.dataSource(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 51 common frames omitted
感谢
答案 0 :(得分:0)
对于Inject可以使用以下依赖
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
注意:我使用了这种依赖