I am trying to use olap4j with Play 2.1.0 but am having great difficulty in getting some olap4j code to work in a Play controller, this same code works just fine in a separate Eclipse Java project, hence I have ruled out any issues with olap4j or my XMLA server it connects to. I have added the olap4j JAR files as unmanaged dependencies by placing the JAR files in \lib folder. I am running in Play DEV mode.
The following code returns the exception below:
Java Code:
Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
Error:
[RuntimeException: java.lang.NoClassDefFoundError: edu/emory/mathcs/backport/java/util/concurrent/Callable]
After some further digging around I found that Play uses it's own Classloader, so I tried the following:
Java Code:
Play.application().classloader().loadClass("org.olap4j.driver.xmla.XmlaOlap4jDriver");
This seems to eliminate the NoClassDefFoundError error, however the following exception is raised:
Error:
java.sql.SQLException: No suitable driver found for jdbc:xmla:Server=http://localhost/OLAP/msmdpump.dll
Perhaps I need to add the JDBC class registration in a Global class? Any help would be much appreciated. The JavaDocs for org.olap4j.driver.xmla.XmlaOlap4jDriver says the following, which is exactly what I am following:
Since olap4j is a superset of JDBC, you register this driver as you would any JDBC driver: Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver"); Then create a connection using a URL with the prefix "jdbc:xmla:".
Full Code:
package controllers;
import play.Play;
import play.mvc.*;
import org.olap4j.*;
import org.olap4j.metadata.Member;
import java.sql.*;
public class Test extends Controller {
public static Result index() {
String server = "http://localhost/OLAP/msmdpump.dll";
String user = "user";
String password = "password";
String result = "0";
try {
//Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
Play.application().classloader().loadClass("org.olap4j.driver.xmla.XmlaOlap4jDriver");
try {
Connection connection = DriverManager.getConnection("jdbc:xmla:Server="+server, user, password);
} catch (SQLException e) {
result = e.getMessage();
}
} catch (ClassNotFoundException e) {
result = e.getMessage();
}
return ok(result);
}
}
According to this thread, your first approach should work just fine, e.g. this:
Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
The error you're getting,
java.lang.NoClassDefFoundError: edu/emory/mathcs/backport/java/util/concurrent/Callable
implies that you need to add backport-util-concurrent.jar
also to your class path (like mentioned in this thread). I guess it should work after that. That jar is Backport Concurrent Util jar, available on its site. Place that also into your lib folder.