If anyone feels like tackeling this one here's the code which I've got so
far. It doesn't actually work and it could well be completely the wrong way
to go about this.

It shouldn't break any existing code but if you add a classpath attribute to
the SQL task it will attempt to use it and then fall over with an
IllegalAcessException.

I'd be very interested to see if anyone can get this to work, but since I
can still use the glabal classpath to load the drivers from it's not
essential, it would just be nice to have it.

Tah ;o)

-----Original Message-----
From: John Lacey [mailto:[EMAIL PROTECTED]
Sent: 16 August 2000 03:22
To: [EMAIL PROTECTED]
Subject: Re: AntClassLoader and JDBC drivers


Conor MacNeill wrote:
> 
> The driver you are actually loading is a class which implements the Driver
> interface, so there should be no problem in loading it and creating an
> instance. This is true of the Oracle driver we use here. 

It's true of most drivers, due to the Microsoft JVM, which didn't
originally interpret Class.forName as requiring class
initialization. (The requirement has been clarified, and later MS
JVMs respect the requirement.) The workaround was
Class.forName(...).newInstance(), which requires a public no-args
constructor. It is not required, however, for JDBC drivers to
have any public constructors at all.

Java 2 has the nice Class.forName(String, boolean, ClassLoader),
which is probably off-limits, alas.

[EMAIL PROTECTED] wrote:
> 
> Another approach that is useful is to get reference to class
> and try to look up a non-existent method. This forces
> resolution (usually).

I don't see that this is required to work, either, but it seems
like a reasonable followup to trying newInstance (which for most
practical purposes will work).

(For the pedantically inclined, my reading of 12.4.1 suggests
that reflective methods should only cause class initialization
when a corresponding non-reflective action would have, i.e.,
instance creation, method invocation, or field access.)

Jeff Martin wrote:
> 
> I tried to create a wrapper class which I could
> load via the AntClassLoader but just ended up getting
> IllegalAccessExceptions so I've given up.

This seems like the best by-the-book JDK 1.1-compatible approach.
I'm assuming that your wrapper class just calls Class.forName.
Why don't you post the code for your wrapper if you aren't happy
with the workarounds.

John L

Index: src/main/org/apache/tools/ant/taskdefs/SQLExec.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/SQLExec.java,v
retrieving revision 1.5
diff -r1.5 SQLExec.java
57a58
> import org.apache.tools.ant.types.*;
73a75,78
>     /**
>      * Classpath for loading JDBC drivers
>      */
>     private Path classpath = null;
120a126,132
>      * Set the classpath to be used for this compilation.
>      */
>     public void setClasspath(Path classpath) {
>         this.classpath = classpath;
>     }
>     
>     /**
194a207
>         ConnectionLoader connLoader=null;
196c209,224
<             Class.forName(driver);
---
>             if(classpath==null){
>                 Class.forName(driver);
>             }else{
>                 log("Loading jdbc driver "+ driver + " from classpath " + 
> classpath, Project.MSG_VERBOSE);
>                 connLoader = (ConnectionLoader)new AntClassLoader(project, 
> classpath).loadClass("org.apache.tools.ant.tasks.SQLExecConnection").newInstance();
>                 conn = connLoader.getConnection(driver, url, userId, 
> password);
>             }
>         }catch(SQLException e){
>             e.printStackTrace();
>             throw new BuildException("JDBC driver " + driver + " could not be 
> loaded", location);
>         }catch(InstantiationException e){
>             e.printStackTrace();
>             throw new BuildException("JDBC driver " + driver + " could not be 
> loaded", location);
>         }catch(IllegalAccessException e){
>             e.printStackTrace();
>             throw new BuildException("JDBC driver " + driver + " could not be 
> loaded", location);
197a226
>             e.printStackTrace();
203c232,234
<             conn = DriverManager.getConnection(url, userId, password);
---
>             if(connLoader==null){
>                 conn = DriverManager.getConnection(url, userId, password);
>             }
250a282,285
>     public static interface ConnectionLoader{
>         public Connection getConnection(String driver, String url, String 
> userId, String password) throws SQLException, ClassNotFoundException;
>     }
> 

Attachment: SQLExecConnection.java
Description: Binary data

Reply via email to