problem configure JBoss to work with JNDI - java

I am trying to bind connection to the DB using JNDI in my application that runs on JBoss. I did the following:
I created the datasource file oracle-ds.xml filled it with the relevant xml elements:
<datasources>
<local-tx-datasource>
<jndi-name>bilby</jndi-name>
...
</local-tx-datasource>
</datasources>
and put it in the folder \server\default\deploy
Added the relevant oracle jar file
than in my application I performed:
JndiObjectFactoryBean factory = new
JndiObjectFactoryBean();
factory.setJndiName("bilby");
try{
factory.afterPropertiesSet();
dataSource = factory.getObject();
}
catch(NamingException ne) {
ne.printStackTrace();
}
and this cause the error:
javax.naming.NameNotFoundException:
bilby not bound
then in the output after this error occured I saw the line:
18:37:56,560 INFO
[ConnectionFactoryBindingService]
Bound ConnectionManager 'jb
oss.jca:service=DataSourceBinding,name=bilby'
to JNDI name 'java:bilby'
So what is my configuration problem? I think that it may be that JBoss first loads and runs the .war file of my application and only then it loads the oracle-ds.xml that contain my data-source definition.
The problem is that they are both located in the same folder.
Is there a way to define priority of loading them, or maybe this is not the problem at all.
Any idea?

You should use such construction to call Datasource: java:bilby.
You can read more about that here:
Naming and Directory (JNDI) - JBOSS jndi Datasource: jdbc not bound

To check how the datasource is bound in the JNDI tree you should use the jmx-console
http://localhost8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss%3Aservice%3DJNDIView
and invoke the list() method.
Datasources are registered under "jdbc". In your case "jdbc/bilby"
EDIT: That was an example that works for me without spring.
Now found this example which injects a more complete JNDI name.
<bean id="idDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/bilby" />
</bean>

Related

Weblogic exception : javax.naming.NameNotFoundException: Unable to resolve 'jdbc.payment'. Resolved 'jdbc'; remaining name 'payment'

I have this exception when I lookup jndi datasource from weblogic from spring boot application...only after one successful deployment...I mean from the second deployment on.If I restart the container, it will work fine for the first deployment only.
Caused by: javax.naming.NameNotFoundException: Unable to resolve 'jdbc.payment'. Resolved 'jdbc'; remaining name 'payment'
the datasource with the same name and attached to the admin server.
I use docker image : store/oracle/weblogic:12.2.1.4-dev with environment variable PRODUCTION_MODE=dev
update : if I deattach the data source from the server then reattche it again then start the war, It runs successfully for one time againŲ²
update : switched to local installation of weblogic not dockerized any more and the behavior still happens
It's a spring issue...has nothing to do with weblogic.
In the war shutdown, Spring remove the data source form the server JNDI tree, however the data source still up and running on the server.
The action of recreating or even reattaching the data source to target server, add it again to the JNDI tree.
The workaround to solve this behavior is to prevent spring from calling the destroy method of the data source bean
#Primary
#Bean(name = "dataSource",destroyMethod = "")
#Profile("weblogic")
public DataSource dataSourceWeblogic() throws NamingException {
JndiTemplate jndiTemplate = new JndiTemplate();
InitialContext ctx = (InitialContext) jndiTemplate.getContext();
return (javax.sql.DataSource) ctx.lookup(jndi);
}

Cannot cast from ConnectionWrapper to oracle.jdbc.OracleConnection using JAVA1.8 and Tomcat 8.5.28

Why connection is not working after few seconds? Application is hanging up and not running as expected and returning the below error.
java.lang.ClassCastException:
org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
cannot be cast to org.apache.tomcat.dbcp.dbcp2.DelegatingConnection
Below is the code that is used to get the connection:
OracleConnection oracleConnection = (OracleConnection)
((DelegatingConnection)connection).getInnermostDelegate();
using libraries: commons-pool1.6.jar for encryption & tomcat-dbcp.jar for database.
Using encrypted username and password in Tomcat context.xml.
Also, using accessToUnderlyingConnectionAllowed=true in context.xml file.
Issue is with JAVA8 and Tomcat8. Able to work properly with plain credentials, the only issue happens with encrypted credentials.
You shouldn't do casting or unwrapping. Use correct DataSource type in Tomcat 'conf/context.xml' file. In case of Oracle it is: oracle.jdbc.pool.OracleDataSource.
Set also correct driver and factory.
Look at this example of mine:
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Resource name="UNCUNC"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#p260unc4.big.ru:1566:uncunc"
user="dsserv"
password="dsservPass"
connectionProperties="SetBigStringTryClob=true"
maxTotal="20" maxIdle="10"
maxWaitMillis="-1"/>
<JarScanner scanManifest="false"/>
Later in the java code use it like this (don't cast):
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("UNCUNC");
} catch (NamingException e) {
logger.error("DATASOURCE error", e);
}
Connection conn = ds.getConnection();
Should work just fine. Take attention in different versions of Tomcat you need to use 'username' instead 'user' field.
I faced the same issue. After a lot of analysis realized it was classloading issue. Fixed the issue by providing ojdbc jar in shared.loaded (in conf/catalina.properties)
shared.loader="/path/to/ojdbcN_jar/ojdbcN.jar"
This will make sure that the OracleConnection classes are loaded from the same jar in Tomcat and in the deployed webapp.
And in the application where OracleConnection is needed, use the below:
OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
Note: In my application I have ojdbc jar so that my application compiles fine, but when deployed, the jar used will be the one mentioned in shared loader.
Also don't forget to enable accessToUnderlyingConnectionAllowed when creating the Tomcat JDBC connection pool

WSJDBCConnection does not wrap objects of type Oracle jdbc Connection

I am using Websphere liberty server to run my application and I need to use ArrayDescriptor for passing arrays to the oracle stored procedure. I get an exception while unwrapping the connection. I have checked the connection meta data driver information as well and it is showing me oracle.jdbc driver. The code fails at connection unwrapping line.
Connection conn = this.getDataSource().getConnection();
OracleConnection oracleConn = conn.unwrap(oracle.jdbc.OracleConnection.class);
Exception message: java.sql.SQLException: DSRA9122E:
com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection#120edaf does not wrap
any objects of type oracle.jdbc.OracleConnection.
I have added class loader reference for my application in the server.xml as well but that didn't help.
My server.xml looks like :
<dataSource id="datasource" jndiName="jdbc/XXXXXX"
type="javax.sql.XADataSource">
<jdbcDriver libraryRef="ordLib"/>
<properties.oracle databaseName="XXXX" driverType="thin" password="XXXXXX"
portNumber="XXXXXX" serverName="XXXXXX" serviceName="XXXXXX" url="XXXXXX"
user="XXXXXX"/>
</dataSource>
<webApplication id="NAExtractWeb" location="NAExtractWeb.war"
name="NAExtractWeb">
<classloader commonLibraryRef="ordLib"></classloader>
</webApplication>
<library id="ordLib">
<fileset dir="C:\lib" id="fileset" includes="ojdbc6-11.2.0.4.jar"/>
</library>
Also I use this unwrap function in one of my dependent project jar and I have ojdbc dependency(maven) added in my dependent project. Will that affect the unwrapping step?
Here is the method which will get the data source:
public DataSource getDataSource(String dsName) throws BatchException {
try {
return (DataSource) new InitialContext().lookup(dsName);
} catch (Exception e) {
//Code to handle
}
}
Here is the full stack trace:
[6/19/18 17:20:29:340 IST] [process partition0] com.ibm.ws.batch.JobLogger CWWKY0030I: An exception occurred while running the step process.
com.ibm.jbatch.container.exception.BatchContainerRuntimeException: Failure in Read-Process-Write Loop
at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.invokeChunk(ChunkStepControllerImpl.java:704)
at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.invokeCoreStep(ChunkStepControllerImpl.java:795)
at com.ibm.jbatch.container.controller.impl.BaseStepControllerImpl.execute(BaseStepControllerImpl.java:293)
at com.ibm.jbatch.container.controller.impl.ExecutionTransitioner.doExecutionLoop(ExecutionTransitioner.java:118)
at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl.executeCoreTransitionLoop(WorkUnitThreadControllerImpl.java:93)
at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl.executeWorkUnit(WorkUnitThreadControllerImpl.java:155)
at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl$AbstractControllerHelper.runExecutionOnThread(WorkUnitThreadControllerImpl.java:480)
at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl.runExecutionOnThread(WorkUnitThreadControllerImpl.java:89)
at com.ibm.jbatch.container.util.BatchWorkUnit.run(BatchWorkUnit.java:117)
at com.ibm.ws.context.service.serializable.ContextualRunnable.run(ContextualRunnable.java:79)
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: com.ibm.jbatch.container.exception.BatchContainerRuntimeException: java.sql.SQLException: DSRA9122E: com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection#73c25e77 does not wrap any objects of type oracle.jdbc.OracleConnection.
at com.ibm.jbatch.container.artifact.proxy.ItemWriterProxy.open(ItemWriterProxy.java:67)
at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.openReaderAndWriter(ChunkStepControllerImpl.java:954)
at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.invokeChunk(ChunkStepControllerImpl.java:599)
... 14 more
Caused by: java.sql.SQLException: DSRA9122E: com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection#73c25e77 does not wrap any objects of type oracle.jdbc.OracleConnection.
at com.ibm.ws.rsadapter.jdbc.WSJdbcWrapper.unwrap(WSJdbcWrapper.java:459)
at com.fmr.nfiws.batch.writer.DBWriter.open(DBWriter.java:149)
at com.ibm.jbatch.container.artifact.proxy.ItemWriterProxy.open(ItemWriterProxy.java:64)
... 16 more
I just tested this on WebSphere Liberty and the following code worked for me:
#Resource(lookup = "jdbc/oracle")
private DataSource ds;
// ...
Connection conn = ds.getConnection();
OracleConnection oracleConn = conn.unwrap(oracle.jdbc.OracleConnection.class);
My server.xml looks like this:
<dataSource jndiName="jdbc/oracle">
<jdbcDriver libraryRef="oracleLib"/>
<properties.oracle URL="${jdbc.URL}" user="${jdbc.user}" password="${jdbc.password}"/>
</dataSource>
<library id="oracleLib">
<fileset dir="${server.config.dir}/oracle"/>
</library>
<application location="myApp.war" >
<classloader commonLibraryRef="oracleLib"/>
</application>
The important thing to note here is the use of commonLibraryRef on the <classloader> element. If you use privateLibraryRef it will not work because the app and server-defined datasource will use isolated classloaders to load the Oracle JDBC classes.
If this answer isn't helpful to you, please update your question with your server.xml configuration, and also how you are obtaining an instance of your DataSource.
If someone has this problem here is my solution.
My mistake was that I was deploying my application to the dropins folder and if you define an application/webApplication in your server.xml it is ignored. I deployed it somewhere else, set this new location to the application tag and also added the <classloader> in server.xml, left the ojdbc jar as provided in pom.xml and it works now.
But still I had a problem when I was running the application locally, because the ojdbc jar was provided in pom.xml.
My solution was to use reflection to get the system class loader and load the jar at runtime for the local profile.
Hope this helps someone.
I tried the same thing in my local machine, but not worked because of same ojdbc jar available in the liberty run time server path. After removing its works fine.
LibertyRuntime(In project explorer)->
servers(choose the deployed server)->
apps->you could see application-name.war.xml(Please remove the ojdbc jar from the xml).
Make sure the jar is not available in the xml file
Finally start the server, It will work.

Configuring Mysql DataSource with IBM WebSphere Application Server Liberty Profile

I have a spring mvc application which i am deploying on IBM WebSphere Application Server Liberty Profile, the application is supposed to access a mysql database server that is hosted locally. I have added the datasource configuration as follows in the sever.xml file
<dataSource id="springdb" jndiName="jdbc/springdb">
<jdbcDriver javax.sql.XADataSource="com.mysql.cj.jdbc.Driver" libraryRef="mysqlJDBCLib"/>
<properties databaseName="spring_db" password="**********" portNumber="3306" serverName="localhost" user="root"/>
</dataSource>
<library id="mysqlJDBCLib">
<fileset dir="/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql" includes="mysql-connector-java-6.0.6.jar"/>
</library>
I am getting the following stack trace
Caused by: java.lang.RuntimeException: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[springdb]/jdbcDriver[default-0] using the library mysqlJDBCLib. [/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql/mysql-connector-java-6.0.6.jar]
at com.ibm.ws.resource.internal.ResourceFactoryTrackerData$1.getService(ResourceFactoryTrackerData.java:123)
... 77 more
Caused by: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[springdb]/jdbcDriver[default-0] using the library mysqlJDBCLib. [/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql/mysql-connector-java-6.0.6.jar]
at com.ibm.ws.jdbc.internal.JDBCDriverService.classNotFound(JDBCDriverService.java:196)
... 77 more
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
at com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:499)
... 77 more
I have tried the following
Replacing com.mysql.cj.jdbc.Driver with com.mysql.jdbc.Driver and string got the same error
Replacing javax.sql.XADataSource with javax.sql.DataSource and still got the same error
Replacing javax.sql.XADataSource with javax.sql.MysqlConnectionPoolDataSource, same error
Switching out the mysql connector jar from mysql-connector-java-6.0.6.jar to mysql-connector-java-5.1.45-bin.jar, still same error (both the jars are there in the specified file path)
Background info about datasource config:
For all datasources (except for id="DefaultDataSource") the type of DataSource is selected in the following priority:
Use the type class configured on the <dataSource> element, if configured
javax.sql.ConnectionPoolDataSource This option is active in your case
javax.sql.DataSource
javax.sql.XADataSource
(According to Configuring relational database connectivity in Liberty)
If no class is defined for a type, then the next lowest priority will be checked.
By default, Liberty will scan for use the following priority for locating data source implementation class names:
Use the corresponding value configured on the <jdbcDriver> element
Use the default classes for a <properties.DRIVER_TYPE> element. Note that only some JDBC drivers have their own element types. For JDBC drivers that do not have their own properties element (such as MySQL) use the generic <properties> element
Based on the JDBC driver jar name, Liberty will try to guess the implementation class name. This option is active in your case
Reason why your configuration is not working
You've configured your <jdbcDriver> element to say "Use this specific class for XADataSource's", however, the <dataSource> element you've configured is not attempting to create an XADataSource. Using the priority order mentioned above, it will first try to create a ConnectionPoolDataSource (which Liberty has internally mapped to com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource.
To fix the problem:
Specify <dataSource .. type="javax.sql.XADataSource"> in your configuration so that Liberty will try to create an XADataSource instead of a ConnectionPoolDataSource. Then when it tries to create the XADataSource it will look at the class name you've configured on the <jdbcDriver> element.
Specify MySQL's XADataSource class name for the javax.sql.XADataSource property (which is com.mysql.cj.jdbc.MysqlXADataSource) instead of their java.sql.Driver implementation class name.
So your final configuration would look like this:
<dataSource id="springdb" jndiName="jdbc/springdb" type="javax.sql.XADataSource">
<jdbcDriver javax.sql.XADataSource="com.mysql.cj.jdbc.MysqlXADataSource" libraryRef="mysqlJDBCLib"/>
<properties databaseName="spring_db" password="**********" portNumber="3306" serverName="localhost" user="root"/>
</dataSource>
<library id="mysqlJDBCLib">
<fileset dir="/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql" includes="mysql-connector-java-6.0.6.jar"/>
</library>
If you don't specify the type attribute in the dataSource config element, Liberty will try to infer the datasource class to load based on the driver jar filename. In your example, it is incorrectly inferring implementation class names based on a previous mySQL driver. It appears that mySQL has changed the package names of their implementations for DataSource, ConnectionPoolDataSource and XADataSource. I'll open an git issue for this. In the meantime, you can simply specify the type of datasource to create using the type attribute of the dataSource config element and then update your jdbcDriver config element with javax.sql.DataSource="com.mysql.cj.jdbc.MysqlDataSource" to point to the proper mysql driver class. If instead you need a conn pool or XA datasource instead, just update the type attribute of dataSource to identify the type and update jdbcDriver with the driver class impl.

How to set up jndi.properties for DataStore?

I'm struggling to set connect a Java program to MySQL using JPA/Hibernate.
I'm currently getting the following error when I try to call createEntityManagerFactory():
[main] ERROR org.hibernate.connection.DatasourceConnectionProvider - Could not find datasource: java:jdbc/myDataDS
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.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:75)
Googling seems to indicate that I need a jndi.properties file in META-INF in my classpath, but I can't seem to find any information about what that file should contain in my case.
Edit: I'm running this stand-alone, for the time being.
A jndi.properties file should be at the root of the classpath and typically contains the URL of the JNDI server and the initial context factory to use. For example, with JBoss:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
But, when using Hibernate, you should actually declare these properties in the hibernate.cfg.xml. For example, with WebLogic:
<property name="jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="jndi.url">t3://127.0.0.1:7001</property>

Categories