Русский English Тэги View Sergey Zolotaryov's profile on LinkedIn Вход
Toplink Essentials на Weblogic 10
Постоянная ссылка 25-04-2007 anydoby java

Сегодня весь день мигрировали с 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. Просто убрали из persistence.xml - теперь используем Kodo. Кстати, переход на него занял не так уж и много усилий. Я потралил около 2-х часов на мелкие фиксы, связанные с тем, что Kodo более строго относится к типам параметров запросов. Но в целом должен сказать, что на первый взгляд явных отличий в работе и производительности между Toplink и Kodo не замечено. Время покажет, конечно же :)

Добавить комментарий

Предыдущая статья Ubuntu на ноутбуке HP nx7400 Следующая статья MyFaces не вызывает валидаторы, если поле пустое