Путаница из -за разрешения класса в Oracle Java хранящихся процедурах

StackOverflow https://stackoverflow.com/questions/597022

Вопрос

Я пытаюсь использовать стороннюю библиотеку Java в Oracle. Библиотека кажется совместимой с той же 1,4 версией JVM, что и наши хосты Oracle 10G Server, поскольку она работает нормально за пределами Oracle, поэтому я чувствую, что смогу заставить это работать. Эта библиотека в конечном итоге делает HTTP-запросы на основе SOAP, и я получаю ошибки разрешения класса, когда я работаю в Oracle.

Вот линия, которая показывает разницу:

Class msgfact = Class.forName("com.sun.xml.messaging.saaj.soap.MessageFactoryImpl");

Я попытался зарегистрировать эти библиотеки в Oracle с утилитой LoadJava, и я получил то, что, как я думал, было успешным результатом:

C:\>loadjava -verbose -schema MYUSER -user MYUSER/MYPWD@dbinstance -force saaj-impl.jar

Похоже, что все загружается, и я вижу этот класс MessageFactoryImpl в этом списке. Но затем я пытаюсь запустить эту строку кода из Oracle SQL (внутри другого класса, который я написал и загружен с помощью LoadJava), эта линия бросает ClassNotFoundException (java.lang.classnotfoundexception: com/sun/xml/message/saaj/soap/messagefactorimpl: com/sun/xml/saaj/soapfactoryimp )

Затем я вернулся и попытался добавить переключатель «-resolve» в командной строке LoadJava. Это действует так, как эти классы SAAJ зарегистрированы, но они не решаются должным образом.

Как я могу успешно получить эти классы SAAJ в Oracle, или если по какой -то причине Oracle уже загружен, как я могу убедить свой собственный код успешно использовать существующий класс?

FWIW, я уже предпринял шаги, чтобы убедиться, что соответствующие разрешения на сокет были предоставлены, и мой код может успешно сделать общий HTTP -запрос на целевой URL. У него просто есть проблемы с использованием мыла библиотеки, чтобы это произошло.

РЕДАКТИРОВАТЬ: Вот образец моего результата LoadJava. Похоже, что это показывает именно то, что терпит неудачу, но я не понимаю, почему эти конкретные классы не решаются, когда они, кажется, обрабатываются должным образом на шагах до разрешения. Я исключил около 80% файла здесь, но есть другие классы, которые показывают те же проблемы с разрешением класса.

arguments: '-verbose' '-schema' 'MYSCHEMA' '-user' 'MYSCHEMA/MYSCHEMA@actest' '-resolve' '-force' 'saaj-impl.jar' 
[snip]
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/GifDataContentHandler
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/GifDataContentHandler
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/JpegDataContentHandler
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/JpegDataContentHandler
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl
[snip]
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/AttachmentPartImpl
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/Envelope
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/SOAPPartImpl could not be resolved
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/GifDataContentHandler
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/JpegDataContentHandler
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl could not be resolved
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/impl/EnvelopeImpl could not be resolved
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl$1
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl could not be resolved
skipping : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl$2
[snip]
The following operations failed
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory: resolution
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl: resolution
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl: resolution
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl$1: resolution
[snip]
exiting  : Failures occurred during processing
Это было полезно?

Решение

Прежде всего, проверьте за пределами Oracle, что класс, который вы ищете, на самом деле находится в этом файле JAR. Я ожидаю, что это так, но не повредит проверить.

Затем я бы проверил, какие классы были загружены и есть ли у них действительные статусы.

SELECT object_name, dbms_java.longname(object_name), status
  FROM user_objects
  WHERE object_type='JAVA CLASS'
  ORDER BY 1

Вы можете немного ограничить это, если есть много занятий, например:

WHERE dbms_java.longname(object_name) LIKE '%MessageFactoryImpl'

Если класса там нет, или его там с неправильным именем пакета, то проблема заключается в команде LoadJava.

Если класс есть, но его статус недействителен, проверьте user_errors, чтобы увидеть, каковы ошибки. Я не помню, если бы я сделал динамическую загрузку класса в Oracle, но я помню, что статическое связывание дало бы ошибки, которые подразумевают, что класс не существует, когда он действительно существовал, но имел ошибки.

Новая информация после вывода LoadJava опубликовано

Выход LoadJava кажется непоследовательной с вашей попыткой найти класс в базе данных. Если он загружается, но не решается, его все равно следует перечислить, но с неверным статусом.

Я получил банку и сам попробовал ее в пустой схеме. Класс загружается, но является недействительным, как и ожидалось:

dev> select object_name, dbms_java.longname(object_name),status
  2  from user_objects
  3  where object_name like '%MessageFactoryImpl';

OBJECT_NAME
--------------------------------------------------------------------------------
DBMS_JAVA.LONGNAME(OBJECT_NAME)
--------------------------------------------------------------------------------
STATUS
-------
/3e484eb0_MessageFactoryImpl
com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
INVALID

Затем я проверил, что была ошибка в классе:

dev> alter java class "com/sun/xml/messaging/saaj/soap/MessageFactoryImpl" resolve;
dev> /

Warning: Java altered with compilation errors.

dev> show error
Errors for JAVA CLASS "/3e484eb0_MessageFactoryImpl":

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      ORA-29521: referenced name javax/xml/soap/MessageFactory could
         not be found

0/0      ORA-29521: referenced name javax/xml/soap/SOAPMessage could not
         be found

0/0      ORA-29521: referenced name javax/xml/soap/MimeHeaders could not
         be found

0/0      ORA-29521: referenced name javax/xml/soap/SOAPException could not
         be found

(Эти ошибки также будут перечислены в user_errors, предполагая, что разрешение было предпринято как минимум один раз.)

Так ясно, что этот класс ссылается на классы из базовой библиотеки SOAP. Вы тоже должны были бы загрузить это - вы сделали это?

К вашему сведению, когда я пишу какой -то код для выполнения звонка class.forname (), я получаю ClassNotFoundException. Что может показаться нелогичным, поскольку объект класса существует в схеме. Тем не менее, недопустимый класс на самом деле не «существует» с точки зрения загрузчика класса в Oracle; и для того, чтобы класс был действительным, Oracle должен иметь возможность разрешить все свои ссылки на другие классы.

Другие советы

Это первый раз, когда вы выполняете Java в базе данных? Вот реализация Hello World, чтобы убедиться, что ваш Oracle JVM работает должным образом, и у вас есть необходимые разрешения. Вы сказали: «Моя схема базы данных, так что я могу делать все, что хочу», -это не значит, что у вас есть правильные гранты.

SQL> create or replace and compile java source named "Hello" as 
   public class Hello{ 
      public static String world() { 
         return "Hello World "; 
      } 
   }; 
/ 

Java created. 

Теперь функция обертки

SQL> create or replace function Hello RETURN VARCHAR2 
     as LANGUAGE JAVA NAME 'Hello.world() return String'; 
     / 

Function created.

Теперь проверьте это

SQL> select Hello from dual; 

HELLO 
----------------------------------- 
Hello World 

Сделай это:

try
{
    System.out.println("Class.forName returned: " + 
        Class.forName("com.sun.xml.messaging.saaj.soap.MessageFactoryImpl"));
}
catch(final Throwable ex)
{
    ex.printStackTrace();
    System.exit(1);
}

Просто чтобы быть на 100 и 10% уверен, что это не бросает исключение, которое каким -то образом скрыто и что он действительно возвращает NULL. Если это все еще так, пожалуйста, дайте мне знать (интересная проблема, если приведенный выше код работает, но возвращает NULL).

Попробуйте # 3 :-) (Я не использую Oracle ... но это аккуратная проблема для отладка ...)

Информация здесь на классе.

http://download.oracle.com/docs/cd/b14117_01/java.101/b12021/appover.htm#i1006547

Это представляет собой проблему загрузчика класса, так что решение, решение соответствует тому же, что и в мире «реального, не оракула» :-)

Изменить ... еще одна попытка ...

Хорошо, посмотрю на это еще немного ... какова вывода следующего:

System.out.println("vm vendor:     " + System.getProperty("java.vendor"));
System.out.println("vm version:    " + System.getProperty("java.version"));
System.out.println("class version: " + System.getProperty("java.class.version"));

Мне интересно, есть ли проблема с версией файла класса - есть ли файлы классов версию, которую нельзя запустить на виртуальной машине Oracle?

Разрешение класса и нагрузка являются сложными операциями, обрабатываемыми виртуальной машиной. Алгоритм, который будет использоваться этими двумя операциями, как описано в спецификации, остается открытым для ревизоров VM. Я чувствую, что в вашем случае разрешение работает, поскольку операция проверяет только наличие самого класса, в то время как оно не удается позже, когда пытается эффективно загрузить класс (скорее всего, из -за отсутствующих зависимостей: при загрузке класса необходима виртуальная машина. решить, по крайней мере, все прямые ссылки на другие классы). Вы должны убедиться, что все классы доступны для Oracle, и выполнение быстрого поиска в Google ORA-29534 показывает тонны людей, имеющих эту проблему (и я уверен, что кто-то это понял).

./Алекс

SAAJ-IMPL.JAR является частью компонента SAAJ Pack Developer Pack. Например, он имеет зависимости от других банок, которые поставляются с Saaj, это определенно зависит от Saaj-Api.jar и Activation.jar, насколько мне известно. Конечно, Saaj-Api.jar также обязательно будет зависеть от многих других банок.

Что касается JWSDP 1.5, вы можете найти информацию в Jwsdp 1.5. быть полезным. JWSDP 1.6 имеет разные банки в Saaj, я не нашел выпуск JWSDP 2.0, которые были особенно полезны в этом отношении. Кстати, у JWSDP 2.0 будут разные банки, которые будут размещены в обмене класса; Таким образом, объем вашей проблемы в конечном итоге зависит от версии Saaj-Impl.jar, которую вы используете.

На случай, если вам это может понадобиться, некоторая документация уже доступна о том, как загрузить банки клиентов SOAP в базу данных Oracle и использовать их на следующих страницах. Я предполагаю, что это отличается от банок Saaj, которые поставляются с вашей библиотекой.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top