2

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 (?)

William
  • 1,154
  • 1
  • 9
  • 15
  • Did you registered driver before making connection? Using Class.forName("Driver.something"); – Abhi Apr 01 '18 at 15:02
  • No, because 1) that hasn't been needed since JDBC 4 and 2) I'm using JPA (EclipseLink) so I'm not manually creating the connection – William Apr 01 '18 at 16:09
  • Yes I'm aware that since JDBC 4 it's not required. As per my knowledge Netbeans support it without registering driver but eclipse does not. But I can not say anything about JPA. Don't worry someone will help you ☺️ or may be you will outsmart yourself. – Abhi Apr 01 '18 at 16:15
  • Thanks @Abhii - let's hope, haha. – William Apr 01 '18 at 16:32
  • 2
    @Abhi It has nothing to do with either NetBeans or Eclipse. It is built into the JRE. Since JDBC 1.4. – user207421 Apr 02 '18 at 01:20
  • 1
    @EJP Since Java 6/JDBC 4 – Mark Rotteveel Apr 02 '18 at 13:06
  • This error is going to be coming from the DriverManager, not EclipseLink directly, which should show in the full exception stack trace. Try putting the jar on the server class path, where ever the eclipselink.jar is, or as a shared library, so it is available to what ever class loader is initiating this stack. The persistence unit is a resource from the context just as a datasource would be, so likely needs be on the server class path as suggested here https://stackoverflow.com/a/19482086/496099 – Chris Apr 02 '18 at 18:32
  • @Chris, thanks but I actually read that SO post - hence my efforts of including the mysql connector JAR in any conceivable Glassfish lib folder, as written in my original post. – William Apr 02 '18 at 18:55
  • Can you create a datasource with your jar setup? – Chris Apr 02 '18 at 21:41
  • @Chris Do you mean a JDBC resource? I didn't try that but creating a data source with Payara should be unrelated to the web application itself. – William Apr 03 '18 at 15:49

3 Answers3

2

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:

  1. 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.

  2. 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>
  1. 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.

Mike
  • 4,852
  • 1
  • 29
  • 48
William
  • 1,154
  • 1
  • 9
  • 15
0

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);
AlToK
  • 1
0

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.

Fabien M
  • 181
  • 2
  • 3