On Fri, May 18, 2012 at 11:20 AM, Francisco Vides Fernández fvides@dedaloingenieros.com wrote:
El 18/05/12 00:21, Alessio Stalla escribió:
On Thu, May 17, 2012 at 11:04 PM, Francisco Vides Fernández fvides@igaleno.com wrote:
Hello everyone
I intend to use ABCL in one of my projects. I've started to connectiing to a postgresq database via jdbc. I've tried something like:
-------8<------- (add-to-classpath (merge-pathnames #p".m2/repository/postgresql/postgresql/8.4-702.jdbc4/postgresql-8.4-702.jdbc4.jar" (user-homedir-pathname)))
(jstatic "forName" "java.lang.Class" "org.postgresql.Driver") -------8<-------
But it always returns -------8<------- Java exception 'java.lang.ClassNotFoundException: org.postgresql.Driver'. [Condition of type JAVA-EXCEPTION] -------8<------- The jar file exists, and has the proper class inside. I've read the manual, and googled a bit, but still get the same error. I'm using Ubuntu Linux, with OpenJDK 1.6.0_24, and the latest and greatest ABCL downloaded as a binary from ABCL website. Can someone point me what I'm doing wrong?
TL;DR: use (java:jclass "org.postgresql.Driver").
[snip]
Yes, that did the trick, but now I've the following code: --------------8x-------------- (java:jclass "org.postgresql.Driver") #<java.lang.Class class org.postgresql.Driver {67AFF9E8}> ;; the driver loads, yay!
(java:jstatic "getConnection" "java.sql.DriverManager" "jdbc:postgresql://localhost:5432/test") --------------8x-------------- Throws:
--------------8x-------------- Java exception 'java.sql.SQLException: No suitable driver found for jdbc:postgresql://localhost:5432/test'. [Condition of type JAVA-EXCEPTION] --------------8x--------------
But the equivalent java code works: --------------8x-------------- public class JdbcConn { public static void main(String[] args) { try { Class.forName("org.postgresql.Driver"); java.sql.Connection c = java.sql.DriverManager.getConnection("jdbc:postgresql://localhost:5432/test"); } catch(Exception e) { e.printStackTrace(System.err); } } } --------------8x--------------
I fail to see how the ClassLoader machinery affects this. The org.postgresql.Driver class self-registers with driver manager, in a static block of code:
--------------8x-------------- java.sql.DriverManager.registerDriver(new Driver()); --------------8x--------------
But apparently that isn't happening. I've even tried to do that by hand but nothing.
Some clue on what's happening?
Bummer. Classes might not be initialized (or whatever is the correct technical term) when loaded, depending on how you load them. That includes (not) running static initializer code. Evidently jclass is using the wrong method for your use case.
As a workaround, you could try to force initialization of the class by accessing some static field or method or ask for some metadata (jclass-methods, jclass-name, ...). But I don't know if that's guaranteed to work.
Or you can revert to Class.forName, but ensuring to use the overload that takes an explicit classloader, and feeding it the one used by ABCL (look in java.lisp to see how to retrieve it).
On the long term, though, jclass really needs to take an extra argument to force initialization.
Alessio