WildFly 13 datasource getConnection(user, password) doesn't work - java

Using WildFly 13.
I'm trying to get a java.sql.Connection from the datasource that is being defined in stadalone.xml, as so:
ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:jboss/datasources/myDS");
connection = ds.getConnection(user, password);
The above always fails with Caused by: javax.resource.ResourceException: IJ031016: Wrong credentials passed to getConnection, while
ds.getConnection()
works just fine and can retrieve the connection.
Moreover, when getting and inspecting the metadata from the connection retrieved via the no args call, the user and password seem to be the same that I'm passing to the method with arguments but which fails.

The datasource's pool section must include the true attribute in order for this to work.

Related

How to set the jdbc ClientInfo in a MySQL DataSource

In Java with MySQL we want to add the jdbc ClientInfo to identify the source of each query. Currently we can do something like:
try(Connection connection = dataSource.getConnection()){
connection.setClientInfo("ApplicationName", "MyApp");
}
But I need to add it to every connection created and means checking all the source code for places where a new connection is created. I will like to set it to the DataSource level.
So far what works for me is to extends the DataSource with a custom overriden getConnection method that calls setClientInfo. This is not only a dirty workarround but datasource specific.
I have seen that mysql driver has ClientInfoProviders like the default com.mysql.cj.jdbc.CommentClientInfoProvider. A custom ClientInfoProvider can be configured like:
Properties properties = new Properties();
properties.setProperty(PropertyKey.clientInfoProvider.getKeyName(), "foo.bar.CustomClientInfoProvider");
properties.setProperty(APPLICATION_NAME, "MyApp");
HikariConfig dataSourceConfig = new HikariConfig();
dataSourceConfig.setDataSourceProperties(properties);
...
But it is only called if someone calls the getClientInfo in the connection anyway.
So I will like to know:
Is there support in the MySql driver to set the clientInfo in the DataSource just by setting properties?
If there is a way. How can it be done?
I think you can use AspectJ as a possible solution for it. You can create an aspect which will intercept calls of the DataSource.getConnection method and then call the setClientInfo method with configured parameters when the connection is established.

javax.naming.NoInitialContextException with QueryDSL

I am trying to write a simple query using QueryDSL, but my attempt fails with the following exception.
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
I tried executing query the following ways.
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
JPQLQuery query = new HibernateQuery(session);
QClient t = QClient.client;
List<Client> lst = query.from(t).list(t);
System.out.println(lst.size());
And another way.
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("my.package.entities");
EntityManager em = emf.createEntityManager();
JPAQuery query = new JPAQuery(em);
QClient t = QClient.client;
List<Client> lst = query.from(t).list(t);
System.out.println(lst.size());
As stated, both this ways failed with the same exception.
I am using Postrges DB, and the parameters are specified in hibernate.cfg.xml.
Do I need to setup something more for this to work?
The javax.naming package comprises the JNDI API. Since it's just an API, rather than an implementation, you need to tell it which implementation of JNDI to use. The implementations are typically specific to the server you're trying to talk to.
To specify an implementation, you pass in a Properties object when you construct the InitialContext. These properties specify the implementation to use, as well as the location of the server. The default InitialContext constructor is only useful when there are system properties present, but the properties are the same as if you passed them in manually.
As to which properties you need to set, that depends on your server. You need to hunt those settings down and plug them in.
Sample:
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
properties.put("jnp.socket.Factory", "org.jnp.interfaces.TimedSocketFactory");
properties.setProperty("java.naming.provider.url", "jnp://" + remoteHost + :1099");
context = new InitialContext(properties);
or
look for this
Issue

JAVA Datasource

I am trying to use a datasource that I set up on my weblogic server.
datasource JNDI name = thinOracleDataSource
in my code I have the following
public class DAOBean implements java.io.Serializable {
private Connection conn;
public void connect() throws ClassNotFoundException,
SQLException, NamingException {
Context ctx = new InitialContext();
// Lookup using JNDI name.
DataSource ds = (javax.sql.DataSource) ctx.lookup("thinOracleDataSource");
conn = ds.getConnection();
}
But I get this error
javax.naming.NameNotFoundException: While trying to look up /thinOracleDataSource in /app/webapp/PreAssignment2/24911485.; remaining name '/thinOracleDataSource'
am I looking the JNDI name in the right way? or am I missing something? Thanks for any help!!
EDIT:
This is the jndi tree that I can get from the weblogic console
Try naming your datasource jdbc/thisOracleDataSource in Weblogic and reference it as:
DataSource ds = (javax.sql.DataSource) ctx.lookup("jdbc/thinOracleDataSource");
Also, make sure the datasource is "targeted" to your weblogic Java server. All of this can be done in the Weblogic admin console.
Your JNDI key should look like approximately "java:comp/env/jdbc/thinOracleDataSource".
You can verify it by using Weblogic console that allows access (and probably search) in JNDI. So, you can check this manually before writing the code.

Tomcat6 connect to mySQL problems

I've followed another stackover flow thread to get to this point, it was this one here:
Tomcat6 MySql JDBC Datasource configuration
The problem I have is that the line that goes:
Connection conn = ds.getConnection();
from this block:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Eclipse gives me the error getConnection() is undefined for the type DataSource.
Its solution is to do this:
Connection conn = ((java.sql.Statement) ds).getConnection();
No tutorials show the need to do this, and its not working when I do that. I'm using mySQL jar named, mysql-connector-java-5.1.18-bin I've used it with RMI before but never Tomcat, is it the correct type for use with Tomcat?
TIA
If I look into the Java API docs http://docs.oracle.com/javase/6/docs/api/ I find the javax.sql.DataSource interface with a getConnection() method. I assume your DataSource to be something else than one implementing the javax.sql.DataSource interface. What "DataSource" is imported?

Java Oracle connection pooling - Closed Connection exception

This post is intended to be less of a question and more a confirmation that I'm doing things correctly. I've seen many similar posts but I'm not sure I fully understand everything that's been said.
The problem is that, after a certain amount of time, I get an exception when trying to establish a connection to my oracle database. (I'm using Tomcat 6.0 and Spring)
Previously I had the following configuration:
private PoolDataSource poolDataSource = null;
public MainDAOImpl(String url, String username, String password)
throws Exception
{
poolDataSource = PoolDataSourceFactory.getPoolDataSource();
try
{
poolDataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
poolDataSource.setURL(url);
poolDataSource.setUser(username);
poolDataSource.setPassword(password);
}
catch( SQLException e )
{
...
}
}
public List<Object> getValues(String query)
{
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
connection = poolDataSource.getConnection();
preparedStatement = connection.prepareStatement(query);
...
}
catch( SQLException e )
{
...
}
finally
{
//close connections
}
}
However, sometimes the preparedStatement = connection.prepareStatement(query); threw an SQLException with a "Closed Exception" message.
It's important to note that the MainDAOImpl's constructor gets called only once per server restart (it's dependency injected via Spring).
I've recently changed my setup like so:
private DataSource dataSource = null;
public MainDAOImpl()
throws Exception
{
try
{
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/myOracleConn");
}
catch( NamingException e )
{
...
}
}
and poolDataSource.getConnection() to dataSource.getConnection().
I've also added the following Resource to my Context in Tomcat:
<Resource name="jdbc/myOracleConn" auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="<myURL>"
username="<myUsername>" password="<myPassword>"
maxActive="20" maxIdle="10" maxWaith="-1" />
This basically follows http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html word-for-word.
Everything seems to be working. My question is, will these changes solve my closed connection problem or is there something different I need to do?
Thanks,
B.J.
First of all, if you are using Spring for dependency injection, I would recommend that you also use DI to inject the DAO's dependencies into it.
In other words, your DAO should have a DataSource injected into it, rather than the DAO implementation knowing either 1) what type of DataSource to construct or 2) how and where to look it up in JNDI. Spring can handle JNDI lookups for you.
I'd also recommend using Spring's JdbcTemplate, as it makes for a great wrapper over raw JDBC calls yourself.
Finally, the actual exception you are getting may just be because the database server is closing long-open connections. Not sure which connection pool implementation you are using, but in commons-dbcp there is an option for a "validationQuery" which the pool will execute before returning a connection to verify the connection is still valid. I'm sure most other pools supply similar features, which I would recommend here - this way your DAO is never receiving stale connections from the pool.

Categories