1

I have an RCP application with different plugins. In two of my plugins I need to connect to SQL Server Database using Windows Integrated Authentication.The first one that is loaded works fine but the second one throws the exception:

Native Library sqljdbc_auth.dll already loaded in another classloader

My code is

Plugin A -> SqlRead.java

static{
    try {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Class.forName("net.sourceforge.jtds.jdbc.Driver");
    } catch (ClassNotFoundException e) {
      e.PrintStakeTrace();
    }
}

private Connection openConnection(String connectionString) throws SQLException{
    return DriverManager.getConnection(connectionString);
}  

Plugin B -> Mirror.java

static {
    try {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Class.forName("net.sourceforge.jtds.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    init();
}

public void run(){
    try {
                this.source=DriverManager.getConnection(EaDbStringParser.eaDbStringToJdbc(this.sourceString));
                this.source.setReadOnly(true);              
            } catch (Exception e) {
                if (logView != null)
                    logView.log(new Status(Status.INFO, symbolicName, "cannot establish connection", e));
            }
}

In both the plugins I have loaded the sqljdbc4.jar in the manifest file under classpath and also the dll

The manifest is as:

  Bundle-ClassPath: .,
  external:$sqljdbc_driver_location$/sqljdbc4.jar
  Bundle-NativeCode: external:$sqljdbc_driver_location$/auth/x86/sqljdbc_auth.dll 

In the plugin A it works fine but in plugin B I get the following exception

   com.microsoft.sqlserver.jdbc.SQLServerException: This driver is not configured for integrated authentication. ClientConnectionId:f4ad6643-4d5e-4cfd-9f9f-585af3707186
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
at com.microsoft.sqlserver.jdbc.AuthenticationJNI.<init>(AuthenticationJNI.java:60)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:2229)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$000(SQLServerConnection.java:41)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:2220)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1326)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.intel.imc.swa.jetdb.mirror.Mirror.run(Mirror.java:163)
at com.intel.imc.swa.featuremodel.swamodel.mirror.MirrorFeatureModel.run(MirrorFeatureModel.java:59)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.lang.UnsatisfiedLinkError: Native Library C:\sqljdbc_4.0\enu\auth\x86\sqljdbc_auth.dll already loaded in another classloader
at java.lang.ClassLoader.loadLibrary1(Unknown Source)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at com.microsoft.sqlserver.jdbc.AuthenticationJNI.<clinit>(AuthenticationJNI.java:35)
... 14 more

Edit

Under my Eclipse installation i have

C:/users/uiqbal/Desktop/Eclispe/sqljdbc_auth.dll 

The dll is present in this location and also under

C:/sqldriver/enu/auth/x86/sqljdbc_auth.dll

if I remove the dll from my eclipse installation then the first time I try to make the connection it fails complaining that no dll is found under java class path.

I created a new plugin and inside the manifest I added

 Bundle-NativeCode: external:$sqljdbc_driver_location$/auth/x86/sqljdbc_auth.dll

Where

  $sqljdbc_driver_location = C:/sqldriver/enu

when I try to make the connection again using

 DriverManager.getConnection(EaDbStringParser.eaDbStringToJdbc(this.sourceString));

I get the following error

 WARNING: Failed to load the sqljdbc_auth.dll cause : Native Library C:\Users\uiqbal\Desktop\FM_Eclipse\sqljdbc_auth.dll already loaded in another classloader

Any idea how can I resolve this issue?

Ragnar
  • 645
  • 8
  • 28

1 Answers1

0

The VM can only load the DLL once whether it's running as OSGi/RCP or not.

You'll need to separate the loading of the DLL and sqljdbc4.jar into a third plugin C then have both A and B depend on it.

Nick Wilson
  • 4,959
  • 29
  • 42
  • You mean I should create a plugin Project C in which I put the jar and dll and add Project C in the dependencies of project A and B.? – Ragnar May 28 '15 at 13:29
  • I don't want the jar and dll to be the part of my product. I want them to be on my local file system – Ragnar May 28 '15 at 13:33
  • You can still have plugin C load them from the local file system. The main thing is that only one ClassLoader attempts to load the DLL. – Nick Wilson May 28 '15 at 13:58
  • So the Plugin C will just be a raper plugin which only loads teh jar and dll and plugin A & B should depends on Plugin C right? – Ragnar May 28 '15 at 14:10
  • let me give it a try I will get back to you – Ragnar May 28 '15 at 14:30