Java JPA класс для MATLAB
Я использую MATLAB R2007b, Java 1.6 SE, Eclipse Helios и MySql 5 в Windows XP Pro SP3.
Я пытаюсь создать библиотеку классов, которая использует аннотации JPA для доступа к базе данных MySql 5. Идея состоит в том, что сценарий MATLAB создает экземпляры этих объектов Java, которые предоставляют API для доступа к БД.
Я могу создавать свои аннотированные классы, которые работают в Eclipse (то есть тест JUnit). Я могу экспортировать код в банку, которую я могу запустить из командной строки.
Я обновляю MATLAB Java classpath с помощью javaaddpath(). Я могу создать свой класс в MATLAB. Но когда я вызываю свой init(), который вызывает javax.persistence.Persistence.createEntityManagerFactory(), я получаю страшные
"Отсутствует поставщик сохраняемости для EntityManager"
Эта ошибка обычно означает, что файл persistence.xml находится не в нужном месте. Но это должно быть потому, что мой кувшин работает из командной строки. Добавление папки META-INF в путь Java-класса MATLAB не помогает. Также не происходит извлечение jar-файла и добавление извлеченной структуры папок в путь к классам, независимо от того, добавлен или нет META-INF.
У кого-нибудь есть идеи, сумасшедшие или нет? Кто-нибудь когда-либо делал это в любой версии MATLAB.
Благодарю.
-reilly.
5 ответов
Ну, я нашел "ответ". Где-то, прежде чем я увидел пост о разнице в "динамических" и "статических" cp в MATLAB. "Статический" cp - это текстовый файл, который загружается при запуске. "Динамический" cp загружается во время выполнения, и вы обычно манипулируете им с помощью вызовов m-script. Это то, что я пытался сделать.
Поэтому я добавил свои банки в динамический путь, и это не сработало.
Я добавил их в конец статического пути и получил РАЗНЫЕ ошибки, которые, похоже, относились к разбору XML. Прогресс!
Затем я добавил свои баночки в начало статического пути, и это работает.
Процитирую Барт Симпсон.
Спасибо за все ваши идеи. Задайте мне вопрос C#, чтобы я мог ответить взаимностью...
-reilly.
При работе с Java в MATLAB я часто сталкивался с проблемами с динамическим путем к классам. В качестве обходного пути, используя classpath.txt
до сих пор решил любую проблему.
Работа с различными средами, например, тестирование и производство, приводит к множественным classpath.txt
файлы в вашем начальном каталоге MATLAB. Использование разных версий MATLAB добавляет еще один множитель к числу classpath.txt
файлы вокруг.
ClassPathHacker.java - это опция для динамического добавления классов и jar-файлов в статический путь к классам. При таком подходе не нужно трогать classpath.txt
больше. Ваша конфигурация Java classpath может оставаться в заданном месте startup.m
,
Это всего лишь продолжение вашего ответа о статических и динамических путях классов. Вот функция, которая позволит вам диагностировать, где класс Java загружается из Matlab, и если есть какие-либо маскировки определений классов, возможно, именно поэтому он был чувствителен к упорядочению для вас. Вы можете увидеть другие столкновения; по крайней мере dom4j.jar и commons-collection.jar поставляются с Matlab, но я не знаю, какие версии.
function whereisjavaclassloadingfrom(ClassName)
%WHEREISJAVACLASSLOADINGFROM Show where a Java class is loaded from
%
% whereisjavaclassloadingfrom(ClassName)
%
% Shows where a Java class is loaded from in this Matlab session's JVM.
% This is for diagnosing Java class load problems, such as classpath
% ordering issues, seeing if a class of a given name is included in an
% unexpected JAR file, etc.
%
% Displays output to console.
%
% Examples:
%
% whereisjavaclassloadingfrom('java.util.HashMap')
% whereisjavaclassloadingfrom('com.ldhenergy.etools.MxUtil')
% whereisjavaclassloadingfrom('com.google.common.collect.Maps')
% whereisjavaclassloadingfrom('org.apache.commons.math.complex.Complex')
% Use javaArray to get Class object without having to instantiate. This
% lets it work with objects that have private or non-zero-arg constructors,
% and avoids side effects of object construction.
% (Would use java.lang.Class.forName(), because that's a more direct way of
% doing this, but it doesn't work for stuff on the dynamic classpath.)
ja = javaArray(ClassName,1);
klass = ja.getClass().getComponentType();
klassLoader = klass.getClassLoader();
if isempty(klassLoader)
% JVM used null to represent the "bootstrap" class loader
% I think that's the same as the "system" class loader
klassLoader = java.lang.ClassLoader.getSystemClassLoader();
end
klassLoaderStr = char(klassLoader.toString());
klassFilePath = [strrep(ClassName, '.', '/') '.class'];
try
% This logic assumes that the classes exist as files in the class
% loader. It's a valid assumption for mainstream class loaders,
% including the one's I've seen with Matlab.
klassUrl = klassLoader.getResource(klassFilePath);
if isempty(klassUrl)
klassUrlStr = '';
else
klassUrlStr = char(klassUrl.toString());
end
catch err
klassUrlStr = sprintf('ERROR: %s', err.message);
end
% Get all locations, to reveal masked definitions
urls = enumeration2array(klassLoader.getResources(klassFilePath));
disp(sprintf('Version: %s\nClass: %s\nClassLoader: %s\nURL: %s', version,...
char(klass.getName()), klassLoaderStr, klassUrlStr));
if numel(urls) > 1
disp('Class is masked:');
for i = 1:numel(urls)
disp(sprintf('URL %d: %s', i, char(urls(i))));
end
end
%%
function out = enumeration2array(jenum)
tmp = {};
while jenum.hasMoreElements()
tmp{end+1} = jenum.nextElement();
end
out = [tmp{:}];
Убедитесь, что у вас есть jar-провайдер JPA (например, eclipselink.jar) на вашем пути к классам.
Вы абсолютно уверены, что правильно написали название единицы персистентности в призыве к:
javax.persistence.Persistence.createEntityManagerFactory(String puName)
Это также даст вам ту же ошибку. Имя чувствительно к регистру.