Play Framework 2.1.0 - NoClassDefFoundError при регистрации драйвера JDBC с использованием Class.forName
Я пытаюсь использовать olap4j с Play 2.1.0, но испытываю большие затруднения в том, чтобы заставить некоторый код olap4j работать в контроллере Play, этот же код прекрасно работает в отдельном проекте Eclipse Java, поэтому я исключил любые проблемы с olap4j или мой сервер XMLA, к которому он подключается. Я добавил JAR-файлы olap4j как неуправляемые зависимости, поместив JAR-файлы в папку \lib. Я бегу в режиме Play DEV.
Следующий код возвращает исключение ниже:
Java-код:
Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
Ошибка:
[RuntimeException: java.lang.NoClassDefFoundError: edu/emory/mathcs/backport/java/util/concurrent/Callable]
После некоторого дальнейшего изучения я обнаружил, что Play использует свой собственный Classloader, поэтому я попробовал следующее:
Java-код:
Play.application().classloader().loadClass("org.olap4j.driver.xmla.XmlaOlap4jDriver");
Кажется, это устраняет ошибку NoClassDefFoundError, однако возникает следующее исключение:
Ошибка:
java.sql.SQLException: No suitable driver found for jdbc:xmla:Server=http://localhost/OLAP/msmdpump.dll
Возможно, мне нужно добавить регистрацию класса JDBC в глобальный класс? Любая помощь приветствуется. JavaDocs для org.olap4j.driver.xmla.XmlaOlap4jDriver говорит следующее, именно это я и следую:
Поскольку olap4j является расширенным набором JDBC, вы регистрируете этот драйвер так же, как и любой другой драйвер JDBC: Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver"); Затем создайте соединение, используя URL с префиксом "jdbc:xmla:".
Полный код:
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);
}
}
2 ответа
Согласно этой теме, ваш первый подход должен работать просто отлично, например:
Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
Ошибка, которую вы получаете,
java.lang.NoClassDefFoundError: edu/emory/mathcs/backport/java/util/concurrent/Callable
подразумевает, что вам нужно добавить backport-util-concurrent.jar
также к вашему пути к классам (как упомянуто в этой теме). Я думаю, это должно сработать после этого. Это банка Backport Concurrent Util, доступная на его сайте. Поместите это также в вашу папку lib.
Похоже, вы используете оба olap4j и olap4j-jdk14. Вам нужен только один из двух.