Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hibernate reverse engineering in Netbeans gives NullPointerException [JDBC325] #371

Closed
firebird-automations opened this issue Sep 20, 2013 · 11 comments

Comments

@firebird-automations
Copy link

Submitted by: @mrotteveel

Performing a Hibernate reverse engineering in Netbeans leads to a NullPointerException in the wizard.

See:
http://stackoverflow.com/questions/14500429/nullpointerexception-in-netbeans-hibernate-mapping-files-and-pojos-wizard-from-f
http://stackoverflow.com/questions/18904451/how-to-configure-jaybird-with-hibernate

Looking at the Hibernate (3.2) and Netbeans code involved, the problem seems to be in the way that Netbeans creates the connection in org.netbeans.modules.hibernate.util.CustomJDBCConnectionProvider and this somehow leads to a null connection being returned from Firebird. This might be a classloading issue.

The specific code (which matches with the logging in Netbeans) in CustomJDBCConnectionProvider (based on 7.3.1 source) is:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class clazz = classLoader.loadClass(driverClassName);

java.sql.Driver driver = (java.sql.Driver) clazz.newInstance();

http://logger.info("Loaded JDBC driver ");
// Establish the connection
java.util.Properties info = new java.util.Properties();
info.setProperty("user", username);
info.setProperty("password", password);
connection = driver.connect(driverURL, info);
http://logger.info("Got connection.. returning");

Looking at org.firebirdsql.jdbc.FBDriver this can only return null if GDSFactory.getTypeForProtocol(url); does not return a GDSType, which should only happen if the URL is not a Firebird url.

Commits: 6c2e2f5 e8e217e 769ebed e0d05d6 FirebirdSQL/fbt-repository@7f6fb80 FirebirdSQL/fbt-repository@1dee1ca FirebirdSQL/fbt-repository@bb1c405 FirebirdSQL/fbt-repository@c00a50d

@firebird-automations
Copy link
Author

Modified by: @mrotteveel

Version: Jaybird 2.2.2 [ 10480 ]

Version: Jaybird 2.2.1 [ 10474 ]

Version: Jaybird 2.2 [ 10053 ]

Version: Jaybird 2.1.6 [ 10285 ]

@firebird-automations
Copy link
Author

Modified by: @mrotteveel

Fix Version: Jaybird 2.2.4 [ 10531 ]

Fix Version: Jaybird 2.3 [ 10440 ]

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

Added logging to debug this in Netbeans and the problem is indeed that somehow the driver fails to locate the GDSType for the url, the logging I added shows:

INFO [org.netbeans.modules.hibernate.util.HibernateUtil]: Found pre-existing database connection.
INFO [org.netbeans.modules.hibernate.util.HibernateUtil]: Database Connection not established, connecting..
INFO [org.firebirdsql.jdbc.AbstractDriver]: Load event of driver
INFO [org.firebirdsql.jdbc.AbstractDriver]: Loading url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.wire.WireGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.jni.NativeGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.jni.LocalGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.jni.EmbeddedGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.oo.OOGDSFactoryPlugin
INFO [org.hibernate.connection.ConnectionProviderFactory]: Initializing connection provider: org.netbeans.modules.hibernate.util.CustomJDBCConnectionProvider
INFO [org.firebirdsql.jdbc.AbstractDriver]: Load event of driver
INFO [org.netbeans.modules.hibernate.util.CustomJDBCConnectionProvider]: Loaded JDBC driver
INFO [org.firebirdsql.jdbc.AbstractDriver]: Loading url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.jdbc.AbstractDriver]: No GDSType for url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.netbeans.modules.hibernate.util.CustomJDBCConnectionProvider]: Got connection.. returning

It looks like first the HibernateUtil class (succesfully) loads the driver including the types, and then the CustomJDBCConnectionProvider loads another driver and this Driver somehow can't find the GDSFactoryPlugin types.

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

Added further logging that shows that 1) HibernateUtil succesfully connects, and 2) CustomJDBCConnectionProvider fails to connect because the jdbcUrlToPluginMap is empty.

INFO [org.netbeans.modules.hibernate.util.HibernateUtil]: Found pre-existing database connection.
INFO [org.netbeans.modules.hibernate.util.HibernateUtil]: Database Connection not established, connecting..
INFO [org.firebirdsql.jdbc.AbstractDriver]: Load event of driver
INFO [org.firebirdsql.jdbc.AbstractDriver]: Loading url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.wire.WireGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.jni.NativeGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.jni.LocalGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.jni.EmbeddedGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to load class org.firebirdsql.gds.impl.oo.OOGDSFactoryPlugin
INFO [org.firebirdsql.gds.impl.GDSFactory]: Finding type for url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.gds.impl.GDSFactory]: Entry count in jdbcUrlToPluginMap: 7
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to match protocol jdbc:firebirdsql:oo: and plugin GDS implementation for OpenOffice.
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to match protocol jdbc:firebirdsql:native: and plugin JNI-based GDS implementation.
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to match protocol jdbc:firebirdsql:local: and plugin JNI-based GDS implementation using IPC communication.
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to match protocol jdbc:firebirdsql:java: and plugin Pure Java GDS implementation.
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to match protocol jdbc:firebirdsql:embedded: and plugin GDS implementation for embedded server.
INFO [org.firebirdsql.gds.impl.GDSFactory]: Attempting to match protocol jdbc:firebirdsql: and plugin Pure Java GDS implementation.
INFO [org.firebirdsql.gds.impl.GDSFactory]: Matched protocol jdbc:firebirdsql: of plugin Pure Java GDS implementation. to url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.jdbc.AbstractDriver]: Returned connection org.firebirdsql.jdbc.FBConnection@10ddee69
INFO [org.hibernate.connection.ConnectionProviderFactory]: Initializing connection provider: org.netbeans.modules.hibernate.util.CustomJDBCConnectionProvider
INFO [org.firebirdsql.jdbc.AbstractDriver]: Load event of driver
INFO [org.netbeans.modules.hibernate.util.CustomJDBCConnectionProvider]: Loaded JDBC driver
INFO [org.firebirdsql.jdbc.AbstractDriver]: Loading url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.gds.impl.GDSFactory]: Finding type for url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.gds.impl.GDSFactory]: Entry count in jdbcUrlToPluginMap: 0
INFO [org.firebirdsql.gds.impl.GDSFactory]: No protocol match found for url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true
INFO [org.firebirdsql.jdbc.AbstractDriver]: No GDSType for url jdbc:firebirdsql://localhost/D:/data/db/testdatabase.fdb?columnLabelForName=true

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

A closer look at org.netbeans.modules.hibernate.util.CustomClassLoader shows that the issue is with the custom classloader that netbeans uses for Hibernate:

@OverRide
public Enumeration<URL> findResources(String name) throws IOException {
if (name.startsWith("META-INF/services")) { //NOI18N
return Collections.enumeration(Collections.<URL>emptyList());
} else {
return super.findResources(name);
}
}

This prevents Jaybird from loading the GDSFactoryPlugin implementations.

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

This problem will also impact the new wire protocol (or more specifically: encodings and ProtocolDefinitions) in Jaybird 2.3, as those are also loaded from META-INF/services

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

Committed for 2.2.4: As a workaround, the GDSFactory will now load a hardcoded list of classes if none were loaded through the META-INF/services file(s).

I will further investigate this for 2.3.

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

Released a 2.2.4 snapshot that includes this fix to sourceforge: http://sourceforge.net/projects/firebird/files/firebird-jca-jdbc-driver/2.2.4-SNAPSHOT/

@firebird-automations
Copy link
Author

Commented by: @mrotteveel

Added comment to https://netbeans.org/bugzilla/show_bug.cgi?id=159004

@firebird-automations
Copy link
Author

Modified by: @mrotteveel

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Fixed [ 1 ]

@firebird-automations
Copy link
Author

Modified by: @mrotteveel

status: Resolved [ 5 ] => Closed [ 6 ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment