Сегодня весь день мигрировали с Weblogic 9.2 на 10. В общем ничего сложного, почти все так же, да вот только при запуске webapp, использующего JPA имплементацию Toplink Essentials, возникли непонятные проблемы. Вы когда-нибудь видели такую ошибку?
java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:335)
at oracle.toplink.essentials.ejb.cmp3.persistence.ArchiveFactoryImpl.cre
ateArchive(ArchiveFactoryImpl.java:85)
at oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcesso
r.readStandardMappingFiles(MetadataProcessor.java:358)
at
oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcesso
r.readMappingFiles(MetadataProcessor.java:339)
at oracle.toplink.essentials.ejb.cmp3.persistence.PersistenceUnitProcess
or.processORMetadata(PersistenceUnitProcessor.java:344)
Truncated. see log file for complete stacktrace
Долго искали, кто виноват и что делать. Оказалось, виноваты оба, и Weblogic, и Toplink. Вот кусочек кода, который бросает ошибку:
public Archive createArchive(URL url) throws URISyntaxException, IOException {
logger.entering("ArchiveFactoryImpl", "createArchive", new Object[]{url});
Archive result;
String protocol = url.getProtocol();
logger.logp(Level.FINER, "ArchiveFactoryImpl", "createArchive", "protocol = {0}", protocol);
if ("file".equals(protocol)) {
URI uri = null;
try {
// Attempt to use url.toURI since it will deal with all urls
// without special characters and URISyntaxException allows us
// to catch issues with special characters. This will handle
// URLs that already have special characters replaced such as
// URLS derived from searches for persistence.xml on the Java
// System class loader
uri = url.toURI();
} catch (URISyntaxException exception) {
// Use multi-argument constructor for URI since single-argument
// constructor and URL.toURI() do not deal with special
// characters in path
uri = new URI(url.getProtocol(), url.getUserInfo(),
url.getHost(), url.getPort(),
url.getPath(), url.getQuery(), null);
}
File f = new File(uri);
При попытке создать файл из URI кидается вышеописанная ошибка. Почему же нет ошибки в Weblogic 9? Дело в том, что под 9-м Weblogic этот код даже не выполняется, потому что url параметр метода createArchive имеет протокол zip и выполняется простая операция чтения из jar файла, а в Weblogic 10 в метод передается url с протоколом file, что и вызывает ошибку.
После длительного копания в коде топлинка выяснилось, что на Weblogic 9 используется родная имплементация javax.persistence.spi.PersistenceUnitInfo (SEPersistenceUnitInfo), так как нативной поддержки JPA нету, и метод getJarFileUrls() возвращает urlы с "правильным" протоколом - zip. А Weblogic 10 это JEE5 контейнер, в котором есть своя реализация JPA - Kodo. И соответственно топлинку передается из контейнера имплементация javax.persistence.spi.PersistenceUnitInfo от Weblogic. А она в свою очередь из метода getJarFileUrls() возвращает урлы с протоколом file :(, от которых у топлинка едет крыша.
И как это решить, спросите вы %) если горит, то просто удалите ветку if ("file".equals(protocol)). Как сделал я. Но по-хорошему, конечно, надо запостить баг на glassfish и ждать фикса.
Вот такие пироги
PS. Да, естественно, такое решение не годится для серьезного проекта по вполне очевидным причинам. Поэтому самым простым решением было отказаться вообще от Toplink Essentials. Просто убрали
