[armedbear-devel] Connection to database via JDBC and classpath
Alessio Stalla
alessiostalla at gmail.com
Fri May 18 10:14:20 UTC 2012
On Fri, May 18, 2012 at 11:20 AM, Francisco Vides Fernández
<fvides at 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 at 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
--
Some gratuitous spam:
http://ripple-project.org Ripple, social credit system
http://villages.cc Villages.cc, Ripple-powered community economy
http://common-lisp.net/project/armedbear ABCL, Common Lisp on the JVM
http://code.google.com/p/tapulli my current open source projects
http://www.manydesigns.com/ ManyDesigns Portofino, open source
model-driven Java web application framework
More information about the armedbear-devel
mailing list