What is classpath for Groovy Console / jdbc driver

2019-01-15 22:56发布

Such database code is OK in Java environment (without binded value 'c'), but in Groovy console can't properly use jdbc, with exception

java.sql.SQLException: No suitable driver found for jdbc:sqlserver://localhost;databaseName=

Driver class is known for script (is loaded without null etc) but probably not registered in Drivermanager ?

code (i try with and without Class.forname() )

import groovy.sql.Sql
import groovy.sql.DataSet

c =   Class.forName('com.microsoft.sqlserver.jdbc.SQLServerDriver')

def db = [url:'jdbc:sqlserver://localhost;databaseName=... ,driver:'com.microsoft.sqlserver.jdbc.SQLServerDriver']
 def sql = Sql.newInstance(db )

EDIT: what I had checked already:

  1. fresh started Groovy console hasn't sqljdbc4.jar on classpath.

Natural exception java.lang.ClassNotFoundException on line 4 Class.forName(), or if line 4 commented and parameters db with driver name the exception on line 7 Sql.newInstance(db )

Its logical, driver class not found etc ...

1a. if db parameters with 3 arguments (without driver), I assume its legal (and working in other situations) exception changes to SQLException: No suitable driver on line 7 Sql.newInstance(db )

It is logical too, DriverManager don't know how to resolve key jdbc:sqlserver . Driver isn't registered and DriverManager have not magical knowledge what class implements.

2. when I add jar to console classpath (Script / Add jar(s) to classpath) things are somewhat changed. No more ClassNotFoundException and variable c has non-null value (driver class) but SQLException: No suitable driver continues.

My understanding of JDBC philosophy: (modern) JAR driver uses technique with file META-INF/services/java.sql.Driver to be known for DriverManager. So in correct situation 4th argument (driver class name) is not required because is discovered automatically. Please correct my understanding if I'm wrong.

I have used word 'active' in this sense ("non active" means class exist and is loaded, but can be used as jdbc driver).

My maximal code is:

import groovy.sql.Sql
import groovy.sql.DataSet
import java.sql.DriverManager;
import java.util.ServiceLoader;


c =   Class.forName('com.microsoft.sqlserver.jdbc.SQLServerDriver')
DriverManager.getDrivers()
ServiceLoader.load(java.sql.Driver.class)
def db = [url:'jdbc:sqlserver://localhost;...,driver:'com.microsoft.sqlserver.jdbc.SQLServerDriver']
def sql = Sql.newInstance(db )

but still no suitable driver Exception

EDIT2: I enumerate things with such code (before newInstance() ):

StringBuilder sb = new StringBuilder();
        String grVersion = "brak";

        Enumeration<Driver> dri = DriverManager.getDrivers();

        for (Enumeration<Driver> e = dri; e.hasMoreElements();) {
            Driver e1 = e.nextElement();
            sb.append(e1.getClass().getName()).append(' ');
            sb.append(e1.getMajorVersion()).append('.').append(e1.getMinorVersion());
        }


        // get LOADED drivers niesetty

        ServiceLoader<java.sql.Driver> codecSetLoader = ServiceLoader.load(java.sql.Driver.class);
        for (Driver e1 : codecSetLoader) {
            sb.append(e1.getClass().getName()).append('!');
            sb.append(e1.getMajorVersion()).append('.').append(e1.getMinorVersion());
            sb.append("# ");
        }

and get

com.mysql.jdbc.Driver 5.1com.mysql.fabric.jdbc.FabricMySQLDriver 5.1com.mysql.jdbc.Driver!5.1# com.mysql.fabric.jdbc.FabricMySQLDriver!5.1# com.microsoft.sqlserver.jdbc.SQLServerDriver!4.0#  
Exception thrown

java.sql.SQLException: No suitable driver found for jdbc:sqlserver://localhost;databaseName=....

    at ConsoleScript11.run(ConsoleScript11:32)

My (basic) code executed is Tomcat environment still working ok. What's the matter?

2条回答
再贱就再见
2楼-- · 2019-01-15 23:16

Autor's answer:

When driver JAR is added "dynamic" from menu (like written over) is visible but not working as JDBC.

When driver JAR is dropped into ...console\lib catalogue (between other JAR'a of Groovy) all OK.

This level of investigation is enough for me, maybe someone try to find bug in menu. Can I accept (green) my own answer?

查看更多
成全新的幸福
3楼-- · 2019-01-15 23:17

Solution for today, is add the following at beginning of script. Using groovy 2.5.

@Grab('com.microsoft.sqlserver:sqljdbc4:4.0')
@GrabConfig(systemClassLoader=true)
查看更多
登录 后发表回答