J'ai configuré une application Spring Boot (v 1.1.9) à déployer en tant que fichier WAR. Et j'essaie d'intégrer cette application Web à un module de service de données existant (ajouté en tant que dépendance maven).
Environnement essayant de déployer: WebSphere Application Server 8.5.5.4
Le problème auquel je suis confronté est un échec de démarrage de l'application lorsque vous essayez de rechercher une source de données JNDI ( jdbc/fileUploadDS ) comme ci-dessous dans le module de service de données dépendant.
@Configuration
@Profile("prod")
public class JndiDataConfig implements DataConfig {
@Bean
public DataSource dataSource() throws NamingException {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("Java:comp/env/jdbc/fileUploadDS");
}
}
Ma configuration de démarrage du printemps:
@Configuration
@ComponentScan(basePackages = { "au.com.aiaa.fileupload.data.*", "demo" })
@EnableAutoConfiguration(exclude = { HibernateJpaAutoConfiguration.class, DataSourceAutoConfiguration.class })
public class SampleApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<SampleApplication> applicationClass = SampleApplication.class;
@Bean
public static Properties fileUploadJndiProperties() throws NamingException {
JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
jndiFactoryBean.setJndiName("props/FileUploadProperties");
jndiFactoryBean.setExpectedType(Properties.class);
jndiFactoryBean.setLookupOnStartup(true);
jndiFactoryBean.afterPropertiesSet();
return (Properties) jndiFactoryBean.getObject();
}
}
Notez que je suis capable de rechercher props/FileUploadProperties avec succès. Mais ne pas faire la même chose pour une source de données.
Mon doute est qu'il essaye de charger un EmbeddedWebApplicationContext qui n'est pas ce que je veux.
La trace de la pile est:
Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource() throws javax.naming.NamingException] threw exception; nested exception is **javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "Java:".**
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:301)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.Java:1186)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:482)
at **org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.Java:109)**
at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:320)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.Java:142)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.Java:89)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.Java:51)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.Java:175)
..................
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource() throws javax.naming.NamingException] threw exception; nested exception is **javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "Java:".**
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:586)
... 132 common frames omitted
Caused by: javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "Java:".
at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.Java:1970)
at com.ibm.ws.naming.ipbase.NameSpace.retrieveBinding(NameSpace.Java:1377)
at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.Java:1220)
at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.Java:1142)
at com.ibm.ws.naming.urlbase.UrlContextImpl.lookupExt(UrlContextImpl.Java:1436)
at com.ibm.ws.naming.Java.javaURLContextImpl.lookupExt(javaURLContextImpl.Java:477)
at com.ibm.ws.naming.Java.javaURLContextRoot.lookupExt(javaURLContextRoot.Java:485)
at com.ibm.ws.naming.Java.javaURLContextRoot.lookup(javaURLContextRoot.Java:370)
at org.Apache.aries.jndi.DelegateContext.lookup(DelegateContext.Java:161)
at javax.naming.InitialContext.lookup(InitialContext.Java:436)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource(JndiDataConfig.Java:41)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe.CGLIB$dataSource$0(<generated>)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe$$FastClassBySpringCGLIB$$3c9e0518.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.Java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.Java:312)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe.dataSource(<generated>)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:60)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:37)
at Java.lang.reflect.Method.invoke(Method.Java:611)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:166)
Qu'est-ce que j'oublie ici? Même lorsque j'essaie de définir explicitement la méthode de bean dataSource dans SampleApplication.Java, comme ci-dessous, il échoue avec la même erreur.
@Bean
public static DataSource dataSource() throws NamingException {
JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
jndiFactoryBean.setJndiName("Java:comp/env/jdbc/fileUploadDS");
jndiFactoryBean.setExpectedType(DataSource.class);
jndiFactoryBean.setLookupOnStartup(true);
jndiFactoryBean.setResourceRef(true);
jndiFactoryBean.afterPropertiesSet();
return (DataSource) jndiFactoryBean.getObject();
}
J'ai mentionné ceci et il est indiqué que nous devons définir enableNaming () sur le conteneur de servlets? Puis-je faire quelque chose de similaire pour un contexte d'application Web non incorporé? Ou est-ce purement un problème WAS 8.5?
Vous devez avoir une référence de ressource avec jdbc/fileUploadDS
nom dans votre web.xml
. Et assurez-vous qu'il est lié au nom actuel de la source de données lors de l'installation ou via le fichier ibm-web-bnd.xml
.
Définition dans web.xml
:
<resource-ref>
<description />
<res-ref-name>jdbc/fileUploadDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Si vous ne souhaitez pas utiliser web.xml
, dans l'application Java EE normale, vous pouvez simplement ajouter au composant Web (servlet, filtre) l'annotation de classe suivante:
@Resource(name="jdbc/fileUploadDS", type=javax.sql.DataSource.class, lookup="jdbc/fileUploadDS")
mais je ne suis pas un expert de Spring-boot, donc je ne sais pas si cela fonctionnera ou est possible là-bas.
Je suis confronté au même problème. Je ne sais pas comment définir une balise au démarrage du printemps car il n'y a pas de fichier web.xml dans le démarrage du printemps.
Jusqu'à présent, ce que j'ai appris, c'est que nous devons le définir dans le dossier de candidature à partir duquel nous commençons notre candidature de printemps. Je pense que nous devons utiliser cette méthode pour définir la source de données:
@Bean(destroyMethod="")
@ConfigurationProperties(prefix="datasource.mine")
public DataSource dataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("Java:jdbc/configurationFile");
}
Je viens de configurer Spring Boot avec ma source de données personnalisée comme suit:
@Bean
@ConfigurationProperties("spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
et à l'intérieur du fichier application.properties, j'ai défini tous les paramètres de la source de données comme d'habitude
spring.datasource.driver-class-name= ***
spring.datasource.url= ***
spring.datasource.username= ***
spring.datasource.password= ***
spring.datasource.jndi-name=jdbc/myDB
Cela ne fonctionne pas bien avec @SpringBootApplication avec tous les autres paramètres par défaut
Merci
Je peux connecter mon application Spring-Boot (déployée dans Websphere Application Server 9) à la source de données WAS. Le code suivant a fonctionné pour moi pour la connexion à DataSource:
@Bean(name = "WASDataSource")
public DataSource WASDataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("DSNAME");
}
@Bean(name = "WASDataSourceJdbcTemplate")
public JdbcTemplate jdbcTemplate_WASDS(@Qualifier("WASDataSource")
DataSource dsDB2) {
return new JdbcTemplate(dsDB2);
}
Remarque: Le nom de la source de données "DSNAME" est le nom qui apparaît sur l'interface utilisateur de la console Websphere. Vous pouvez le voir via -> Sélectionnez Ressources> JDBC> Sources de données.
Ensuite, j'ai créé le modèle jdbc:
@Autowired
@Qualifier("WASDataSourceJdbcTemplate")
private JdbcTemplate db2WASTemplate;`
Et exécuter une requête en utilisant la méthode de requête fonctionne bien:
db2WASTemplate.query ()
Je n'ai créé aucun fichier Web.xml ou ibm-web-bnd.xml