Unable to create a connection pool in Java + MySQL + Vibur-dbcp - java

I am trying to create a conection pool whit vibur-dbcp for an app for desktop in JavaFX , i got a MySQL database in AWS and works great when i connect from Workbench butt when i connect from the app the response time increments, i check my code and the reason is because the app creates to many connections creating to much overheat (firts the app have a embedded SQLite databese and the conections weren't a problem) i remake the estructure of my code butt i still need to make alot of conections.
looking for a solution i find that conection pool is the way, i find a good number of solutions Apache commons, C3P0, HikariCP and Vibur DBCP i try to use all but at the moment i can't make one to work, i look for a tutorial but i only can find old implementations (Java 6 or older) for servlets and only snippets and all are very confusing for me (im a begginer in DB), my favorite option is HikariCP but i can make the pool to work, my next option is Vibur at the moment i have this code for the conection.
private Connection connection;
//creates the pool
public DataSource createDataSourceWithStatementsCache() {
ViburDBCPDataSource ds = new ViburDBCPDataSource();
ds.setJdbcUrl("dbURL");
ds.setUsername("dbUser");
ds.setPassword("dbPass");
ds.setPoolInitialSize(10);
ds.setPoolMaxSize(100);
ds.setConnectionIdleLimitInSeconds(30);
ds.setTestConnectionQuery("isValid");
ds.setLogQueryExecutionLongerThanMs(500);
ds.setLogStackTraceForLongQueryExecution(true);
ds.setStatementCacheMaxSize(200);
ds.start();
return ds;
}
//Getts the conection
public Connection conectarBD(){
try {
connection = createDataSourceWithStatementsCache().getConnection();
} catch (SQLException ex) {
Logger.getLogger(coneccionBD.class.getName()).log(Level.SEVERE, null, ex);
}
return connection;
}
public void desconectarBD(){
try {
connection.close();
} catch (SQLException ex) {
Logger.getLogger(coneccionBD.class.getName()).log(Level.SEVERE, null, ex);
}
}
i get this error
Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: org/vibur/objectpool/listener/Listener
at HE.MVC.Modelo.Laboratoriales.Conexion.createDataSourceWithStatementsCache(Conexion.java:36)
at HE.MVC.Modelo.Laboratoriales.Conexion.conectarBD(Conexion.java:63)
at HE.MVC.Modelo.MedicamentosAbituales.cargaTabla(MedicamentosAbituales.java:186)
at HE.MVC.Vistas.Paciente.NuevopacienteController.iniciaTablas(NuevopacienteController.java:351)
at HE.MVC.Vistas.Paciente.NuevopacienteController.initialize(NuevopacienteController.java:1156)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at HE.HEstadistica.LanzaNuevoPaciente(HEstadistica.java:304)
at HE.MVC.Vistas.Paciente.EscenaPacientesController$7$1.run(EscenaPacientesController.java:347)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.vibur.objectpool.listener.Listener
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 17 more
what im asking is two things
1.- what i making wrong in this code?.
2.- is there a book, manual, page o videos for learning conecction pool (HikariCP explanation for begginers it would be wonderful) where i can learn how to make this work?

#CorrOrtiz, regarding your first question, what #hotzst suggests in his comment below your question is correct. For Vibur DBCP there are two jar files that you need as dependencies for your application: vibur-dbcp-9.0.jar and vibur-object-pool-9.0.jar. The exception that you're getting means that you're most likely missing the second dependency, although if you've added the vibur-dbcp dependency via Maven then you should have transitively got the second dependency, too.

Related

Exception in thread "reader" java.lang.NoClassDefFoundError: org/bouncycastle/crypto/ec/CustomNamedCurves

I've used 'net.schmizz.sshj.SSHClient' package to connect to a server.
Below is my code:
public class ConnectToServer {
String hostName = "10.250.176.6";
int port = 22;
public ConnectToServer(String hostName, int port) {
this.hostName = hostName;
this.port = port;
}
public void ssh() {
SSHClient ssh = new SSHClient();
String cmd = "ipconfig";
try {
ssh.connect(this.hostName, this.port);
ssh.isConnected();
final Process process = Runtime.getRuntime().exec(cmd);
ssh.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
However, I faced to an error: "Exception in thread "reader" java.lang.NoClassDefFoundError: org/bouncycastle/crypto/ec/CustomNamedCurves".
I added bcprov-jdk15on-1.49 and bouncycastle.jar into my classpath.
Please help me to resolve this error.
Complete exception:
08:46:05.526 [main] DEBUG net.schmizz.concurrent.Promise - Awaiting <<kex done>>
08:46:05.528 [reader] DEBUG n.s.sshj.transport.KeyExchanger - Received SSH_MSG_KEXINIT
08:46:05.528 [reader] DEBUG n.s.sshj.transport.KeyExchanger - Negotiated algorithms: [ kex=curve25519-sha256#libssh.org; sig=ecdsa-sha2-nistp256; c2sCipher=aes128-ctr; s2cCipher=aes128-ctr; c2sMAC=hmac-sha1; s2cMAC=hmac-sha1; c2sComp=none; s2cComp=none ]
**Exception in thread "reader" java.lang.NoClassDefFoundError: org/bouncycastle/crypto/ec/CustomNamedCurves**
at net.schmizz.sshj.transport.kex.Curve25519DH.getCurve25519Params(Curve25519DH.java:60)
at net.schmizz.sshj.transport.kex.Curve25519SHA256.initDH(Curve25519SHA256.java:44)
at net.schmizz.sshj.transport.kex.AbstractDHG.init(AbstractDHG.java:46)
at net.schmizz.sshj.transport.KeyExchanger.gotKexInit(KeyExchanger.java:236)
at net.schmizz.sshj.transport.KeyExchanger.handle(KeyExchanger.java:356)
at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:503)
at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:102)
at net.schmizz.sshj.transport.Decoder.received(Decoder.java:170) at net.schmizz.sshj.transport.Reader.run(Reader.java:59)
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.crypto.ec.CustomNamedCurves
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Your jar is probably missing its dependencies (or some of it.) If its a maven project i suggest you rather switch to Maven.
A nice tutorial can be found here: Maven in 5 Minutes
I think, the SSH Client is missing org.Bouncycastle.crypto as libary (dependency). Quick way to fix this is to get the jar for it too.
This issue might be occurred due to use of different versions of bouncycastle jars in the project.
the solution is ,
to find the different versions of bouncycastle jars getting used directly or indirectly in the project.
try to use one version of bouncycastle jars in whole project.
make changes according to version which you have chosen to use across project as code written with one version of bouncycastle jar may not work for other version of bouncycastle.
Clean your project or rebuild it again.
If the problem is not solved, please post complete exception so that we will get more clarity.

trying to find db connection leak in my code, using Spring / JPA / Hikari

I've got a problem with a Spring web application that periodically runs into an error fetching a connection from my connection pool. Eventually in the logs I see entries like:
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
Only way to recover I've found once it hits this point is to restart Tomcat.
I think the most likely explanation is I have some code somewhere that is not properly cleaning up its connection - returning it to Hikari, leaving something open so Spring can't clean it up, etc.
To troubleshoot I've set my hikari config leakDetectionThreshold to 5000ms and enabled logging. After that, I see log entries like
2018-04-24 19:53:56 WARN ProxyLeakTask:87 - Connection leak detection
triggered for org.postgresql.jdbc.PgConnection#664ec666, stack trace
follows
java.lang.Exception: Apparent connection leak detected
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:99)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:129)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:47)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1940)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1909)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887)
at org.hibernate.loader.Loader.doQuery(Loader.java:932)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
at org.hibernate.loader.Loader.doList(Loader.java:2615)
at org.hibernate.loader.Loader.doList(Loader.java:2598)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430)
at org.hibernate.loader.Loader.list(Loader.java:2425)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2129)
at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:981)
at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:147)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1398)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1444)
at sun.reflect.GeneratedMethodAccessor191.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:379)
at com.sun.proxy.$Proxy163.getSingleResult(Unknown Source)
at com.mycompany.web.jpa.util.DBHelper.getPagedMappedDbResults(DBHelper.java:76)
at com.mycompany.web.jpa.repository.TaskRepositoryImpl.findTaskDetailsByStepIdAndIdIn(TaskRepositoryImpl.java:245)
......
So it is detecting a possible leak. Could be a false positive I suppose? But this is also the only class in my app that is doing database access outside of the standard service/repository pattern often used in Spring apps, so it seems like a likely culprit, and it's my best lead at the moment.
Anyway, the last piece of non library code I see in the trace (ie stuff I wrote, so most likely to be the cause of the leak!) is my DBHelper::getPagedMappedDbResults method, relevant bit included here:
Query q = entityManager.createNativeQuery(countQueryText);
setQueryParameters(q, parameters);
long numActualResults = 0;
try {
numActualResults = ((Number)q.getSingleResult()).longValue(); // line 76
} catch (Exception e) {
System.out.println("just in case: " + e);
}
So basically I create a Query object from my EntityManager instance, set some parameters, and run it to get some results.
Is there something I need to be doing with a Query object when I'm done with it? q.cleanup()? I don't see anything like this from reading the docs, but am I not doing good housekeeping on this resource?
The entityManager itself is created from an #Autowired annotation. My understanding is if I didn't "new" it to instantiate it and instead let the Spring framework autowire it, then Spring will do whatever cleanup is necessary. Is that right? Or do I need to be doing some cleanup after I use the entityManager?
Version details:
Tomcat 8 / Java 8
Spring 5.0.0.RELEASE
Spring Data Kay-RELEASE
Hibernate 5.2.3.Final
Hikari 2.4.5
Any advice or suggestions would be greatly appreciated, thanks!
What is the query? Is it heavy? Maybe you have deadlock here? Connection management looks fine. You do not acquire connection explicitly, so no need to release it. The query might be long running so Hibernate is not able to complete it and release the connection.
Also, you can check the number of open connections on the DB side. Do some analysis on that side as well.

How to connect to Azure SQL database with jTDS

I try to connect to Azure SQL with:
import java.sql.*;
public class ExampleJTDS {
public static void main(String[] args) {
// Setting.
String connectionUrl = "jdbc:jtds:sqlserver://SERVER.database.windows.net:1433/DATABASE;ssl=off";
String user = "USER#SERVER";
String pass = "PASSWORD";
// Declare the JDBC object.
Connection conn = null;
try {
// Establish the connection.
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn = DriverManager.getConnection(connectionUrl, user, pass);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
But I am getting:
java.sql.SQLException: I/O Error: DB server closed connection.
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2481)
at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:632)
at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:371)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at run.ExampleJTDS.main(ExampleJTDS.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
If I force the encryption by substituting ssl=off with ssl=require, I am getting:
java.sql.SQLException: Network error IOException: Connection reset
at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:436)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at run.ExampleJTDS.main(ExampleJTDS.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Interestingly, I can connect to the database from the same computer and with the same JDBC driver with SQuirreL SQL (although without SSL - SQuirreL SQL manages to put the credentials into the first TDS packet and Azure accepts that). Hence, the problem should not be in the setting of firewalls.
Metadata:
Server: Azure V12
Driver: jtds-1.3.1
JRE: 1.8.0_72-b15 (from Oracle)
_JAVA_OPTIONS: -Djsse.enableCBCProtection=false
security.provider.1: sun.security.provider.Sun
OS: OS X 10.11.5
SQuirreL SQL: 3.7.1
How can I connect to Azure SQL from Java?
Per my experience, I think the issue was caused by the connection string which is the variable connectionUrl of your code. I have answered your similar question of the SO thread, please see How to connect to Azure SQL with JDBC.
However, using jTDS instead of Microsoft JDBC driver for SQL Server has a little difference, you can refer to a note in the step 3 of the tutorial to know it. As reference, I post the contento of the note here.
Note:
If you are using the JTDS JDBC driver, then you will need to add "ssl=require" to the URL of the connection string and you need to set the following option for the JVM "-Djsse.enableCBCProtection=false". This JVM option disables a fix for a security vulnerability, so make sure you understand what risk is involved before setting this option.
Hope it helps. Any concern, please feel free to let me know.

Redis throw exceptioon about "Read time out"

I'm the new to redis, I start the server about this tutorial. And it work. Then I use write the code using java to connect redis, then it's ok, like this:
Jedis jedis = new Jedis("localhost");
System.out.println("Connection to server sucessfully");
//store data in redis list
jedis.lpush("tutorial-list", "Redis");
jedis.lpush("tutorial-list", "Mongodb");
jedis.lpush("tutorial-list", "Mysql");
But, when I use multithread to push the redis, it will throw the exception "read time out":
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: Read timed out at
redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:201)
at
redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
at redis.clients.jedis.Protocol.process(Protocol.java:141) at
redis.clients.jedis.Protocol.read(Protocol.java:205) at
redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
at
redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:233)
at redis.clients.jedis.Jedis.keys(Jedis.java:185) at
org.v11.redis_mongo_task.UpdateApp.jobDetail(UpdateApp.java:23) at
org.v11.redis_mongo_task.UpdateApp.main(UpdateApp.java:42) ... 5 more
Caused by: java.net.SocketTimeoutException: Read timed out at
java.net.SocketInputStream.socketRead0(Native Method) at
java.net.SocketInputStream.read(SocketInputStream.java:150) at
java.net.SocketInputStream.read(SocketInputStream.java:121) at
java.net.SocketInputStream.read(SocketInputStream.java:107) at
redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:195)
... 13 more
What happened for redis? why it can work in single thread?
According to this answer, a single Jedis instance is not threadsafe. You will have to use JedisPool for multithreading. You can read here on how use it and here to set the max connections and what will happen if those connections are all occupied.
I'm posting links since two of them are SO answers an they should get the credit and one is from github official repo, so if anything gets updated it should be reflected here too.

Connecting to MySQL database java

I'm using some code for multi threaded MySQL system. It's working fine and will put entry's into my database in under half a second. My problem is, the rate at which my program will successfully connect and write to the database, is not great. Some of the time it will work fine and other times I'll receive this error, or similar:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 27,697 milliseconds ago. The last packet sent successfully to the server was 1 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1121)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3670)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3559)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4110)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1379)
at MySQL.putEntry(MySQL.java:46)
at MySQL.main(MySQL.java:105)
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3119)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3570)
... 9 more
I'm really not sure why this happens? Executing too many statements from one address??
Anywho, here's my code:
private final ThreadedSQL sql;
private final DatabaseConnection connection;
private PreparedStatement statement;
public Hiscores() {
try {
loadConfig();
} catch (IOException e) {
e.printStackTrace();
}
sql = new ThreadedSQL(config);
connection = sql.getConnectionPool().nextFree();
}
public void putEntry(final Player player) {
try {
statement = connection.getConnection().prepareStatement(QUERY(player));
statement.execute();
statement.closeOnCompletion();
} catch(Exception e) {
e.printStackTrace();
}
}
The code I've not included is irrelevant, uses java.sql.Connection. Does anyone have any idea why this is occuring? Thanks.
You should close your statement and connection, once you are done, otherwise resource pool may be exhausted or your connection may time out. I recommend to obtain new connection from some JDBC pool. I used to use proxool few years ago in servlets environment. If you are in J2EE, then application server shall do it for you, but you have to use DataSource.

Categories