I am using WildFly 8.2 and setup the following external context
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<bindings>
<external-context name="java:global/ldap" module="org.jboss.as.naming" class="javax.naming.ldap.InitialLdapContext" cache="true">
<environment>
<property name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<property name="java.naming.provider.url" value="ldap://example.com:389"/>
<property name="java.naming.security.authentication" value="simple"/>
<property name="java.naming.security.principal" value="CN=exampleuser,DC=example,DC=com"/>
<property name="java.naming.security.credentials" value="examplepassword"/>
</environment>
</external-context>
</bindings>
<remote-naming/>
</subsystem>
I am trying to use this external context to connect to Active Directory with this code:
#Resource(lookup = "java:global/ldap")
private LdapContext ldapCtx;
NamingEnumeration<SearchResult> enumeration = ldapCtx.search();
I get the following errors:
Caused by: java.lang.IllegalArgumentException: JBAS016081: Error injecting resource into CDI managed bean. Can't find a resource named java:global/ldap defined on private javax.naming.ldap.LdapContext com.example.LdapClient.ldapCtx
If I change my code to
#Resource(lookup = "java:global/ldap")
private InitialDirContext iniCtx;
LdapContext ldapCtx = (LdapContext) iniCtx;
NamingEnumeration<SearchResult> enumeration = ldapCtx.search();
I get
Caused by: javax.naming.NamingException: JBAS011878: Failed to lookup ldap [Root exception is java.lang.RuntimeException: java.lang.NoSuchMethodException: javax.naming.ldap.LdapContext.<init>(java.util.Hashtable)]
Looks like you've set the class for your context to the LdapContext interface in the naming subsystem. I believe (and please correct me if I'm wrong as it's been a while since I've done any work with this aspect) this needs to be an actual implementation class, i.e., InitialDirContext, InitialLdapContext, etc. You'll then need to modify your #Resource injection accordingly.
I would have preferred to make this a comment, but not enough points. :)
Related
I was trying to migrate a war deployed in jboss to tomcat 8. I am facing the below exception while loading my application context xml. This was working in jboss. (Had Same issue with dataSource, but it got fixed when I configured <GlobalNamingResources/> settings in context.xml.)
Application context has
..
<jee:jndi-lookup id="txnService" jndi-name="services/TxnService"
lazy-init="true" />
<jee:jndi-lookup id="mailService" jndi-name="services/MailService"
lazy-init="true" expected-type="com.tone.mailservice.MailService" />
..
And error:
Caused by: javax.naming.NameNotFoundException: Name [services/MailService] is not bound in this Context. Unable to find [services].
and
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'txnService': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [services/TxnService] is not bound in this Context. Unable to find [services].
I can see the TxnService class has the following code.
public abstract interface TxnService
{
public static final String JNDI_NAME = "services/TxnService";
..
}
This class is inside a jar and i have that jar inside the lib folder.
I have tried giving java:/comp/env/services/TxnService and java:/comp/env/services/MailService instead. But still same issue.
Full trace:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mailService': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [services/MailService] is not bound in this Context. Unable to find [services].
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1482)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:1146)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1096)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 45 more
Caused by: javax.naming.NameNotFoundException: Name [services/MailService] is not bound in this Context. Unable to find [services].
at org.apache.naming.NamingContext.lookup(NamingContext.java:816)
at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:104)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201)
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)
... 54 more
Related cause:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'txnService': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [services/TxnService] is not bound in this Context. Unable to find [services].
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1482)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getTypeForFactoryBean(AbstractBeanFactory.java:1368)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:720)
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:523)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:356)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:334)
at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:187)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:897)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:855)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1045)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:949)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1183)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1099)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:989)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4940)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5250)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:952)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1823)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
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: javax.naming.NameNotFoundException: Name [services/TxnService] is not bound in this Context. Unable to find [services].
at org.apache.naming.NamingContext.lookup(NamingContext.java:816)
at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
at org.apache.naming.NamingContext.lookup(NamingContext.java:827)
at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
at org.apache.naming.NamingContext.lookup(NamingContext.java:827)
at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201)
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)
... 51 more
Your problem seems to be a JNDI lookup related issue.
Actually, I am trying to provide a fulfill procedure for JBoss to Tomcat migration. Here I have not given the specific answer. Please follow the procedure. After that, if any issue arise, we would start further discussion.
There are mainly 3 areas need to be considered for migration between jboss and tomcat8.
Common libraries,
Data source configutation,
JNDI bindings and basic server configuration
Common libraries:
For Tomcat:
Apache Tomcat stores the common libraries into the CATALINE_HOME/lib folder.
For JBoss:
JBoss AS release ==== Path for common libs
4.x ================= JBOSS_HOME/server/[server-name]/lib
5.x - 6.x============ JBOSS_HOME/common/lib
7.x ================= JBOSS_HOME/modules
Resource Link:
http://www.mastertheboss.com/jboss-as-7/how-to-install-a-module-on-jboss-as-7
Data Source Configuration
If you use Oracle as database then
For Tomcat
A Datasource is configured in the context.xml file of Tomcat:
<Resource name="jdbc/oracledb"
auth="Container"
type="javax.sql.DataSource"
username="scott"
password="tiger"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:#localhost:1521:XE"
maxActive="10"
maxIdle="2"
removeAbandoned="true"
removeAbandonedTimeout="30"
maxWait="5000"
logAbandoned="true"
accessToUnderlyingConnectionAllowed="true"/>
then, you should add your JDBC driver into CATALINA_HOME/lib folder
For JBoss:
JBoss AS release ======== Path for data source
4.x - 5.x - 6.x ======== datasource-ds.xml file into JBOSS_HOME/server/[server-name]/deploy
7.x ===================== datasource-ds.xml file into JBOSS_HOME/standalone/deployments or as a module into JBOSS_HOME/modules
JNDI bindings and basic server configuration
In JNDI binding, code related changing should be required in tomcat. JNDI binding can be done in 2 ways.
Using lookup code
Using the #Resource annotation (javax.annotation.Resource) instead of the lookup code
Using lookup code
We can look up the configured JNDI DataSource using Java code as follows:
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/UsersDB");
Connection conn = ds.getConnection();
After obtaining the connection, we can use it as trivial JDBC code:
And then
Statement statement = conn.createStatement();
String sql = "select username, email from users";
ResultSet rs = statement.executeQuery(sql);
// iterates over the result set...
Using the #Resource annotation (javax.annotation.Resource) instead of the lookup code
It needs to declare a field called dataSource in the servlet like this:
#Resource(name = "jdbc/UsersDB")
private DataSource dataSource;
Tomcat will look up the specified resource name and inject an actual implementation when it discovers this annotation.
For full source code with example, you can go through this tutorial: Configuring JNDI DataSource for Database Connection Pooling in Tomcat
For JBoss:
when using JBoss AS 7 you have to choose a JNDI location like java:/ or java:/jboss for your datasources in order to be accepted. The portable approach for defining data sources is to use a resource reference.
In our example, we need to define into your web.xml for your connection pool:
DB Connection
jdbc/oracledb
javax.sql.DataSource
Container
Alternatively, starting in Java EE 5 (Servlet 2.5), this can be done even easier within your code using the #Resource annotation.
public class MyServlet extends HttpServlet {
#Resource(name = "jdbc/oracledb")
private DataSource dataSource;
Then on the JBoss side define in your jboss-web.xml
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/oracledb</res-ref-name>
<jndi-name>java:jboss/datasources/jdbc/oracledb</jndi-name>
</resource-ref>
</jboss-web>
Fine, now your JNDI lookup will work in either environment, without changing one line of code!
Server Configuration
by default both Tomcat and JBoss are delivering http applications on port 8080, chances are that you might need configuring the http port. Here's tomcat's server.xml
<Connector port="32080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
Resource Link:
Tomcat DataSource JNDI Example in Java
Tomcat to JBoss migration
I have spring boot application setup. Now I need to add Spring JDBC Template to it. While doing this, I am facing below exception.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'XXX': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.jdbc.core.JdbcTemplate com..XXX.jdbcTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.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 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (the profiles "LOCAL" are currently active).
Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (the profiles "LOCAL" are currently active).
Below is the code.
#Service
public class XXX {
#Autowired
JdbcTemplate jdbcTemplate;
public void testDataSource() {
List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from C_MASTER");
System.out.println("list : " + list);
}
}
Java Config
#Configuration
#ComponentScan
#EnableTransactionManagement
public class DAODataServiceManagerConfiguration {
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:#g9u1769.houston.hpecorp.net:1525:ODSDBD");
dataSource.setUsername("Solid_batch");
dataSource.setPassword("solid_batch123");
return dataSource;
}
}
As spring boot looks for application.properties, I have added that too in the resources directory.
appliation.properties.
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:#g9u1769.houston.hpecorp.net:1525:ODSDBD
spring.datasource.username=Solid_batch
spring.datasource.password=solid_batch123
spring.datasource.initialize=true
It is unable to build the application. Correct me if I am doing anything wrong.
You are missing ojdbc jar in your project classpath, follow below steps to download, install and use it as a dependency:
Download ojdbc6.jar from here.
Install it, running command -
mvn install:install-file -Dfile={Path/to/your/ojdbc.jar} -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar
For jar version, extract the jar file and check the Implementation-Version in MANIFEST.MF, for instance:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_51-b10 (Sun Microsystems Inc.)
Implementation-Vendor: Oracle Corporation
Implementation-Title: JDBC
Implementation-Version: 11.2.0.4.0
Repository-Id: JAVAVM_11.2.0.4.0_LINUX.X64_RELEASE
Specification-Vendor: Sun Microsystems Inc.
Specification-Title: JDBC
Specification-Version: 4.0
Main-Class: oracle.jdbc.OracleDriver
sealed: true
Name: oracle/sql/converter/
Sealed: false
Name: oracle/sql/
Sealed: false
Name: oracle/sql/converter_xcharset/
Sealed: false
Name: oracle/replay/driver/
Sealed: false
Add as a dependency in the project, as follows:
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0</version>
</dependency>
Use jdbctemplate by extends JdbcDaoSupport .
By it programmer not concern about the open and close the connection.
Use commons-dbcp2-2.1.1.jar and commons-pool2-2.4.2.jar for use dbcp2 because dbcp2 support Connection pooling.
It's a technique to allow multiple clinets to make use of a cached set of shared and reusable connection objects providing access to a database
public class XXX extends JdbcDaoSupport {
public void testDataSource() {
List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from C_MASTER");
System.out.println("list : " + list);
}
}
In spring.xml write
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/database_name" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="xXX" class="your_package_name.XXX">
<property name="dataSource" ref="dataSource" />
</bean>
I have gone through spring boot reference document. I came to know that if we are using (H2, HSQL or Derby) databases then we don't require application.properties.
If the project is having Oracle database, then application.properties should be updated. In my case I have updated the properties file.
So I have updated only following things, then it worked properly.
pom.xml
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
configuration file
#Configuration
public class DaoConfig {
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
dataSource.setUrl("xxx");
dataSource.setUsername("xxx");
dataSource.setPassword("xxx");
return dataSource;
}
#Bean
public JdbcTemplate getJdbcTemplate() {
return new JdbcTemplate(getDataSource());
}
I hope this might help someone.
Thanks #ChrisThompson and #Arpit
I'm trying to configure Sniffy to work with Oracle. I'm using Glassfish as application server, with JPA 2.0, and EclipseLink as provider.
When EclipseLink tries to allocate the connection, it fails saying that the Oracle URL specified is invalid, because of the "sniffer:" prefix, I guess:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed;
nested exception is javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: Connection could not be allocated because: Invalid Oracle URL specified
Error Code: 0
This is how I configured the pool in my domain.xml file:
<jdbc-resource pool-name="poolGI" object-type="system-all" jndi-name="jdbc/poolGI" />
<jdbc-connection-pool driver-classname="io.sniffy.MockDriver" name="poolGI" res-type="javax.sql.DataSource" datasource-classname="oracle.jdbc.pool.OracleDataSource">
<property name="URL" value="sniffer:jdbc:oracle:thin:#(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=service)))"></property>
<property name="user" value="user"></property>
<property name="password" value="password"></property>
</jdbc-connection-pool>
Sniffy developer here.
Looks like oracle.jdbc.pool.OracleDataSource ignores the driver-classname property and implicitly uses oracle.jdbc.driver.OracleDriver. OracleDriver doesn't know about sniffer: schema, hence the exception.
You need to switch to another data source in order to use Sniffy.
For example Hikari Connection Pool.
I am attempting to register a Hibernate Session Factory from a persistence unit in a applications deployed to WildFly 8.2.1 and I am encountering a warning exception from the Hibernate 4 code (listed below). And when I look at JNDI in the WildFly console, the session factories are definitely not registered. I would like them to be in the "java:app" scope so that I can avoid naming collisions when more that one application might have the same session factory name.
Registering an entity manager to this scope works fine.
If I leave the "java:app" prefix off the session factory name it bind just fine into JNDI, but at a global scope. I understand that I can impose some sort of name-spacing, but I was hoping I would not have to.
Any input would be appreciated. Thank you.
Details below...
The persistence unit
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/jdbc/MyDS</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<mapping-file>MySchema.hbm.xml</mapping-file>
<properties>
<property name="jboss.entity.manager.jndi.name" value="java:app/em/MY_EM" />
<property name="hibernate.session_factory_name" value="java:app/sessions/my_FACTORY"/>
<property name="hibernate.query.imports" value="com.my.model" />
<property name="hibernate.current_session_context_class" value="thread" />
<property name="hibernate.use_outer_join" value="true" />
<property name="hibernate.jdbc.use_streams_for_binary" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
</properties>
</persistence-unit>
Exception snippet
16:14:50,044 WARN [org.hibernate.internal.SessionFactoryRegistry] (ServerService Thread Pool -- 64) - HHH000277: Could not bind factory to JNDI: org.hibernate.engine.jndi.JndiException: Error creating intermediate context [java:app]
Caused by: javax.naming.NameNotFoundException: java:app
Full Warning exception from Hibernate
16:14:50,044 WARN [org.hibernate.internal.SessionFactoryRegistry] (ServerService Thread Pool -- 64) - HHH000277: Could not bind factory to JNDI: org.hibernate.engine.jndi.JndiException: Error creating intermediate context [java:app]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.bind(JndiServiceImpl.java:205) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.bind(JndiServiceImpl.java:159) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.internal.SessionFactoryRegistry.addSessionFactory(SessionFactoryRegistry.java:103) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:497) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.jboss.as.jpa.hibernate4.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44) [jipijapa-hibernate4-3-1.0.1.Final.jar:]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:154) [wildfly-jpa-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:117) [wildfly-jpa-8.2.1.Final.jar:8.2.1.Final]
at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_51]
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:474) [wildfly-security-manager-1.0.0.Final.jar:1.0.0.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:182) [wildfly-jpa-8.2.1.Final.jar:8.2.1.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_51]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_51]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_51]
at org.jboss.threads.JBossThread.run(JBossThread.java:122)
Caused by: javax.naming.NameNotFoundException: java:app
at org.jboss.as.naming.InitialContext$DefaultInitialContext.findContext(InitialContext.java:187) [wildfly-naming-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.as.naming.InitialContext$DefaultInitialContext.createSubcontext(InitialContext.java:294) [wildfly-naming-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.as.naming.NamingContext.createSubcontext(NamingContext.java:398) [wildfly-naming-8.2.1.Final.jar:8.2.1.Final]
at javax.naming.InitialContext.createSubcontext(InitialContext.java:489) [rt.jar:1.8.0_51]
at javax.naming.InitialContext.createSubcontext(InitialContext.java:489) [rt.jar:1.8.0_51]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.bind(JndiServiceImpl.java:202) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
... 18 more
I may have found the answer...
Although it is not exactly the answer I wanted. But, it makes sense. The reason that Hibernate's JNDI binding robots cannot find the java:app subcontext is because, I think, it is attempting to find that name at the root and it does not exist there. JBoss/WildFly on the other have seems to have some implicit context when deploying the application and actually as the java:app existing under the applications/<module-name> inside the JNDI tree. Hibernate doesn't know anything about this structure.
I've modified my implementation is organize these session factory bindings by application name at the root of the JNDI tree like this:
hib > myApp > sessions > MY_SESSION_FACTORY
I hope this helps someone else out.
I am trying to create a datasource bean for MySQL from within my Spring project (in springtoolsuite), and I want to
access the MySQL JNDI (run by JBoss application server).
My Bean declaration
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton" >
<property name="jndiName" value="java:/MySqlDS" />
<property name="resourceRef" value="true" />
And from JBoss console:
java: Namespace
+- MySqlDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
However when I ran my test application, I got the following. What have I done wrong?
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in file [/workspace-sts/test1/cspringbean.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1401)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:540)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
at com.don22.EscortIdol.main(EscortIdol.java:13)
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201)
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1460)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1398)
... 12 more
I would also suggest taking a look at the JEE namespace rather than defining the factory bean
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>
See http://static.springsource.org/spring/docs/2.5.6/reference/xsd-config.html
javax.naming.NoInitialContextException:
Need to specify class name in
environment or system property, or as
an applet parameter, or in an
application resource file:
java.naming.factory.initial
This message in the stack trace leads me to believe that either you didn't set up a JNDI data source pool in JBoss or your JNDI name is incorrect. Check both.
UPDATE: How is your app doing the JNDI lookup with JBOSS? If you aren't deployed in an app server, then you should be using the DriverManagerDataSource, not the JNDI data source.