[armedbear-devel] Connection to database via JDBC and classpath

Alessio Stalla alessiostalla at gmail.com
Thu May 17 22:21:04 UTC 2012


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").

Longer explanation: the JVM loads classes using an abstraction called
a ClassLoader. Different class loaders form separated code
repositories, so to speak. Also, classloaders form a hierarchy,
because each one (except the bootstrap one) has a parent.
Class.forName uses a classloader that does not know about ABCL's
dynamic classloader, i.e. it's not affected by add-to-classpath -
which really has effect only on ABCL, not on the JVM as a whole, as
per the above. ABCL's classloader, on the other hand, does know about
its parent - which is the one used to load abcl.jar, i.e. the system
one in a standalone application, and probably the same Class.forName
will use.

jclass knows and uses the right classloader, so it does what you want.

You *can* use Class.forName if you really want to, because a) ABCL's
classloader is exposed via a dynamic variable (java:*classloader*?
Sorry but I don't remember the details right now...) and b) IIRC
there's an overload for Class.forName that takes an explicit
ClassLoader argument. But I don't see any reason for doing that.

You're not the first to be bitten by those complications, and not just
on ABCL. Any language or library that introduces a mechanism to
dynamically load jars faces the same issues.

I hope I solved your problem, and... have fun with ABCL! :)

Peace,
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