I'm trying to make UCanAccess work in C#. I'm working on MonoDevelop using Mono on Linux. I already converted the needed .jar files into .dll .NET files using IKVM, this way:
ikvmc -target:library file.jar
Then I referenced the converted .dll files in my C# project. So, here is all DLLs I referenced:
I also put ucanaccess-3.0.3.1.jar, hsqldb.jar, jackcess-2.1.3.jar, commons-logging-1.1.1.jar and commons-lang-2.6.jar into my bin/Debug folder.
And here is the C# code I wrote in Main:
//ikvm.runtime.Startup.addBootClassPathAssemby(System.Reflection.Assembly.Load("commons-lang-2.6"));
//ikvm.runtime.Startup.addBootClassPathAssemby(System.Reflection.Assembly.Load("commons-logging-1.1.1"));
//ikvm.runtime.Startup.addBootClassPathAssemby(System.Reflection.Assembly.Load("jackcess-2.1.3"));
//ikvm.runtime.Startup.addBootClassPathAssemby(System.Reflection.Assembly.Load("hsqldb"));
ikvm.runtime.Startup.addBootClassPathAssemby(System.Reflection.Assembly.Load("ucanaccess-3.0.3.1"));
java.sql.Driver v_driver = (java.sql.Driver) java.lang.Class.forName("net.ucanaccess.jdbc.UcanaccessDriver, ucanaccess-3.0.3.1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").newInstance();
java.sql.Connection v_con = v_driver.connect("northwind.mdb", null);
//java.lang.Class.forName("org.hsqldb.jdbcDriver, hsqldb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
//java.lang.Class.forName("net.ucanaccess.jdbc.UcanaccessDriver, ucanaccess-3.0.3.1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
//java.sql.Connection v_con = java.sql.DriverManager.getConnection("jdbc:ucanaccess://northwind.mdb");
java.sql.Statement v_st = v_con.createStatement();
java.sql.ResultSet v_res = v_st.executeQuery("select * from Categories");
java.sql.ResultSetMetaData v_resmd = v_res.getMetaData();
for (int i = 0; i < v_resmd.getColumnCount(); i++)
Console.Write(v_resmd.getColumnLabel(i) + "|");
Console.WriteLine();
while (v_res.next())
{
for (int i = 0; i < v_resmd.getColumnCount(); i++)
Console.Write(v_res.getString(i) + "|");
Console.WriteLine();
}
The code compiles and when I try to execute, here is the error I got:
Unhandled Exception:
System.TypeInitializationException: An exception was thrown by the type initializer for net.ucanaccess.jdbc.UcanaccessDriver ---> java.lang.RuntimeException: org.hsqldb.jdbc.JDBCDriver
--- End of inner exception stack trace ---
at (wrapper managed-to-native) System.Runtime.CompilerServices.RuntimeHelpers:RunClassConstructor (intptr)
at System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (RuntimeTypeHandle type) [0x00000] in <filename unknown>:0
at IKVM.Internal.TypeWrapper.RunClassInit () [0x00000] in <filename unknown>:0
at IKVM.NativeCode.java.lang.Class.forName0 (System.String name, Boolean initialize, java.lang.ClassLoader loader) [0x00000] in <filename unknown>:0
at java.lang.Class.forName0 (System.String , Boolean , java.lang.ClassLoader ) [0x00000] in <filename unknown>:0
at java.lang.Class.forName (System.String className, ikvm.internal.CallerID ) [0x00000] in <filename unknown>:0
at java.lang.Class.forName (System.String className) [0x00000] in <filename unknown>:0
at Test.MainClass.Main (System.String[] args) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for net.ucanaccess.jdbc.UcanaccessDriver ---> java.lang.RuntimeException: org.hsqldb.jdbc.JDBCDriver
--- End of inner exception stack trace ---
at (wrapper managed-to-native) System.Runtime.CompilerServices.RuntimeHelpers:RunClassConstructor (intptr)
at System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (RuntimeTypeHandle type) [0x00000] in <filename unknown>:0
at IKVM.Internal.TypeWrapper.RunClassInit () [0x00000] in <filename unknown>:0
at IKVM.NativeCode.java.lang.Class.forName0 (System.String name, Boolean initialize, java.lang.ClassLoader loader) [0x00000] in <filename unknown>:0
at java.lang.Class.forName0 (System.String , Boolean , java.lang.ClassLoader ) [0x00000] in <filename unknown>:0
at java.lang.Class.forName (System.String className, ikvm.internal.CallerID ) [0x00000] in <filename unknown>:0
at java.lang.Class.forName (System.String className) [0x00000] in <filename unknown>:0
at Test.MainClass.Main (System.String[] args) [0x00000] in <filename unknown>:0
The commented lines I already tried, with no success.
Am I missing something? Thanks in advance!
@jamadei was right, I merged all jars into one single jar and it worked! Here is the working code (note that column indexes start in 1, not in 0):
ikvm.runtime.Startup.addBootClassPathAssemby(System.Reflection.Assembly.Load("ucanaccess-3.0.3.1"));
java.sql.Driver v_driver = (java.sql.Driver) java.lang.Class.forName("net.ucanaccess.jdbc.UcanaccessDriver, ucanaccess-3.0.3.1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").newInstance();
java.sql.Connection v_con = v_driver.connect("northwind.mdb", null);
java.sql.Statement v_st = v_con.createStatement();
java.sql.ResultSet v_res = v_st.executeQuery("select categoryid, categoryname, description from Categories");
java.sql.ResultSetMetaData v_resmd = v_res.getMetaData();
for (int i = 1; i <= v_resmd.getColumnCount(); i++)
Console.Write(v_resmd.getColumnLabel(i) + "|");
Console.WriteLine();
while (v_res.next())
{
for (int i = 1; i <= v_resmd.getColumnCount(); i++)
Console.Write(v_res.getString(i) + "|");
Console.WriteLine();
}
You need to merge all jars into one single jar and then converting it into dll.