jboss connection pool doesn't handle errors gracefully - jboss

I'm using jboss 5.0.1 with multiple data sources configured.
It seems that on startup, if one of those is configured incorrectly, jboss throws an exception and refuses to start.
I would like to know if it's possible to configure jboss to be resilient to these kind of problems.

You can configure the connections in the xml file which holds the connection parameters/mapping. In my case, i am using a microsoft sql server as the datasource, so i have to use the mssql-ds.xml file (inside the server/deploy directory) to specify:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>myTestServer</jndi-name>
<connection-url>jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;databaseName=MyDB</connection-url>
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<user-name>test</user-name>
<password>abc123</password>
<min-pool-size>10</min-pool-size>
<max-pool-size>25</max-pool-size>
<!-- sql to call when connection is created -->
<new-connection-sql>select getdate()</new-connection-sql>
<!-- -->
<!-- sql to call on an existing pooled connection when it is obtained from pool
This will be run before a managed connection is removed from the pool
for use by a client -->
<check-valid-connection-sql>select getdate()</check-valid-connection-sql>
</local-tx-datasource>
</datasources>
This helps control the connections in the pool, and should stop dodgy deadlocks. I'm not entirely sure whether this will test the current transaction level on the connection in question, so if you want to make absolutely sure, you can try: <check-valid-connection-sql>IF ##TRANCOUNT > 0 raiserror ('%s',18,1,'Open Transactions Discovered')</check-valid-connection-sql> This will give you an explicit SQLException to handle.
But if you are getting an error on startup, it would be very useful to see what those errors are.

Related

No suitable driver found for jdbc:mysql://localhost:3306/rom (Payara 5, Windows 10)

Believe me, I know this question has been asked many times and has gotten an answer many times, and these answers seemed to have worked for some users. I've spent many hours trying the various proposed solutions and, while they work on Linux (Ubuntu) they seem to have no effect on Windows (Windows 10 Home with jdk1.8.0_161). The web application is using EclipseLink 2.5.0 for persistence.
I've tried including the mysql-connector-java-5.1.46-bin.jar file in the WAR archive (WEB-INF/lib; using the Deployment Assembly screen in Eclipse), copying it to the payara5/glassfish/lib folder, as well as the payara5/glassfish/domains/domain1/lib/ and payara5/glassfish/domains/domain1/lib/applibs folders. I also tried specifying the library when deploying the web application, i.e., putting mysql-connector-java-5.1.46-bin.jar as the value in the library field. I updated the CLASSPATH environment variable with the path to the JAR file. Every time, the server was restarted. None of these actions have any effect. Note that they did work on Linux Ubuntu.
See below for the well-known exception trace:
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/rom
Error Code: 0
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:326)
at org.eclipse.persistence.sessions.DefaultConnector.connect(DefaultConnector.java:138)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:170)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:228)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:804)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:254)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:757)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:216)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:324)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:348)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:311)
...
Any thoughts would be greatly appreciated.
UPDATE: as a sanity check (got the idea thanks to #Abhi) I added the line
try {
System.out.println("JDBC driver: " +
Class.forName("com.mysql.jdbc.Driver"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Which correctly prints the following line (without throwing an exception):
JDBC driver: class com.mysql.jdbc.Driver
But does nothing to solve the problem. In other words, the driver seems to be loadable but somehow EclipseLink is not able to find it (?)
Looks like I'm able to answer my own question. I asked the exact same question on the Payara Forum and was recommended to define a data source instead of using the driver directly (#Chris pointed in this direction as well). A data source is likely the best way to go anyway but I wanted to avoid the complexity and use the simplest setup .. which clearly didn't work.
For reference, you can find the working setup below:
In Payara 5, goto JDBC > JDBC Connection Pools > New: enter a pool name, select javax.sql.DataSource as resource type, and MySql as vendor. On step 2, com.mysql.jdbc.jdbc2.optional.MysqlDataSource should be preselected for Datasource Classname. Fill out the Username and Password (e.g., root, changeit) properties under the Additional Properties header. Select finish. On the page for the newly created connection pool, select PING to make sure it was setup correctly.
In your persistence.xml file, make sure the persistence-unit element starts as follows:
<persistence-unit name="ROM" transaction-type="JTA">
<jta-data-source>java:global/<connection pool name></jta-data-source>
Create a web.xml file (this may also be done using Java Annotations):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<data-source>
<name>java:global/<connection pool name></name>
<class-name>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</class-name>
<server-name>[host name, e.g., localhost]</server-name>
<port-number>3306</port-number>
<database-name>[db name]</database-name>
<user>[username, e.g., root]</user>
<password>[password]</password>
</data-source>
</web-app>
This configuration worked for me at least. Hoping this will help someone else down the road. Note that there are various useful settings for a connection pool - see e.g., here for more options.
to the line of code to connect:
con = DriverManager.getConnection(urlBaseDatos, usuario, clave);
Add the following:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
con = DriverManager.getConnection(urlBaseDatos, usuario, clave);
Naturally I concur with the answer here, which is "in an Application server you should use a DataSource".
Now just my two cents and to answer the original question:
From JDBC 4, you aren't required to register the driver anymore, and this line shouldn't be necessary:
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
See: https://docs.oracle.com/javase/8/docs/api/java/sql/DriverManager.html
So when using a JDK8+/EE8/JDBC4.2 compliant application server, you shouldn't be mandated to register the driver. Or so I thought...
Though, like you #William, I noticed Glassfish/Payara requires it. It's very strange. Maybe it has to do with the way it handles classloading?
Wildfly, in turn, does the right thing and automatically loads the driver without actually having to manually register it.

TopLink with JPA taking more connections

In my application we are using Toplink with Jpa.
Here the problem is we are using stored procedures in this application, we are taking the connection using Jndi connection for Stored Procedure calling, and we are using EntityManger for remaining queries. But here if we launching the application it is taking two connections from connection pool. After the application launching I am calling the Stored Procedure(sp)
one sp I am taking one connection but in websphere connection pool it is creating two connections?
can U plese help me how to overcome this problem.....
I won't using JTA, to get the JDBC connection I am using
EntityManager em = getJpaTemplate().getEntityManagerFactory().createEntityManager();
this way I am getting the JDBC Connection...and I configured the persitence.xml file following code...
<properties>
<property name="toplink.logging.level" value="OFF"/>
<property name="toplink.cache.type.default" value="NONE"/>
<property name="com.thoughtinc.runtime.persistence.sql.syntax" value="db2" />
</properties>
So, please kindly look into this and tell me any if I am doing any wrong here.
Are you using JTA or non-JTA? Are you releasing the connection back to the pool after using it?
Depending on your configuration (include your persistence.xml), if you have a non-JTA login configured TopLink may use this for non-transactional read queries. This is configurable in your persistence.xml.
To get the JDBC Connection from a TopLink (EclipseLink) EntityManager use em.unwrap(Connection.class)

Connection pooling on a Tomcat 7

I am having issues with implementing connection pooling on a tomcat7.
For some reason tomcat is trying to connect with my machines username. I have been googlin it for a while now but without a luck.
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory
(FATAL: role "caspinol" does not exist)
Cant connect to db
Log In failed: An Exception has occurred! java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)...
My context.xml looks as follows:
<Resource auth="Container" name="jdbc/postgres" type="javax.sql.DataSource" user="biller" password="biller"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432" maxActive="150"
schema="biller" maxIdle="4"/>
And the web.xml:
<resource-ref>
<description>postgreSQL Datasource</description>
<res-ref-name>jdbc/postgres</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I am using jdbc4.jar postgres driver.
I appreciate if somebody can have a look and point out what is the mistake
Thanks in advance
The URL seems to be wrong.
Try this URL :
jdbc:postgresql://localhost:5432/<db_name>
Replace the <db_name> with actual database name.
This is not the right solution here for the issue but would help somebody searching with the same issue with correct connection string.
Check for your network connection access:
Like connection string
jdbc:postgresql://[::1]:5432/<db_name>
uses IPv6,
This will break other connections like accessing wsdl urls from application that are available only via IPv4.
Please hava a look on network connection especially windows 8.

Can JBoss be configured to auto-close JDBC connections for datasources?

For JAAS authentication I have configured a datasource as follows:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>jdbc/SomeDS</jndi-name>
<connection-url>jdbc:path-to-server</connection-url>
<driver-class>interbase.interclient.Driver</driver-class>
<user-name>DBUSER</user-name>
<password>dbpass</password>
<min-pool-size>0</min-pool-size>
<metadata>
<type-mapping>Firebird</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
Unfortunately JBoss keeps the database connection open which can cause severe performance problems on our InterBase database.
As this connection is used only by the JAAS module internally, our web application has no way to force-close the connection.
Is there a way to tell JBoss to close connections after use?
Have you tried adding <idle-timeout-minutes>? - It defines the maximum time a connection may be idle before being closed. Setting to 0 disables it. Default is 15 minutes.
See http://community.jboss.org/wiki/ConfigDataSources for details.

JBoss Database Connection Pool

I am new to jboss and i have been asked to incorporate jboss connection pooling mechanism with an existing web application. Considering that a web application database layer is properly written i.e. all resultsets, statements and connections being closed properly when not needed, What all code changes i will have to make in my web app after i have configured the jboss datasource properly.
Can anybody please point me to a tutorial or a code sample which uses jboss datasource in a web app.
first create an xml file by name xxx-ds.xml and place this file in server/default/deploy/xxx-ds.xml
<datasources>
<local-tx-datasource>
<jndi-name>/jdbc/Exp</jndi-name>
<type-mapping>SQL</type-mapping>
<connection-url>jdbc:microsoft:sqlserver:// </connection-url>
<driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class>
<user-name></user-name>
<password></password>
<min-pool-size>5</min-pool-size>
<max-pool-size>1000</max-pool-size>
</local-tx-datasource>
</datasources>
jboss-web.xml
<jboss-web>
<!-- <security-domain flushOnSessionInvalidation="false"/>-->
<!-- <context-root>/BSI</context-root>-->
<resource-ref>
<description>Database connection resource</description>
<res-ref-name>jdbc/Exp</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:/jdbc/Exp</jndi-name>
<res-auth>Container</res-auth>
</resource-ref>
</jboss-web>
web.xml
<resource-ref>
<description>Database connection resource</description>
<res-ref-name>jdbc/Exp</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
and now in your .java file
javax.naming.Context ctx1 = new javax.naming.InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource) ctx1.lookup("java:comp/env/jdbc/Exp");
con = ds.getConnection();
***** make sure that resource ref name should be same in all place
The pool in JBoss is all handled in the DataSource configuration. Here is the HowTo. The web app would have to do a JNDI lookup for the datasource to get the database connection rather than doing a direct JDBC URL, and then you will have pooling.
Transactions are another story, though.
EDIT: In response to your comment about how this affects the code, this is what it looks like:
String jndiPath = "java:DataSourceJNDIName"; //The exact prefix here has a lot to do with clustering, etc., but if you are using one JBoss instance standalone, this works.
Context ctx = new InitialContext();
DataSource ds = (DataSource) PortableRemoteObject.narrow(ctx.lookup(jndiPath), DataSource.class);
Connection c = ds.getConnection();
Technically speaking the PortableRemoteObject.narrow isn't necessary in a JBoss (4.2.2 anyway) single server configuration for sure, but it is more proper J2EE standard code, as general application servers don't have to return an object of the right type just for doing a Context.lookup.
The above doesn't cover the resource utilization and error handling issues. You are supposed to close that Context object when you are done with it, and of course the database connection, although JBoss will yell at you if you forget to close the database connection and the transaction ends, and close it for you.
Anyway, that Connection object is usable just as much as DriverManager.getConnection(url);
You don't have to change anything.
When you select the right kind of data source (local-tx-datasource / xa-datasource), connection handling and TX is done for you. In $JBoss/docs/examples/jca you will find templates for virtually every database, that you can just reuse.
If you are using XA, you need to configure Tx-recovery. See this posting on a how-to:
http://management-platform.blogspot.com/2008/11/transaction-recovery-in-jbossas.html (well, perhaps not a how-to in the standalone mode, but in conjunction with the Jopr source code).