2011-08-09 8 views
5

Oracle 데이터베이스 저장 프로 시저에서 Java 응용 프로그램으로 지점 간 JMS 메시지를 보내려고합니다. 두 개의 '포인트'는 서로 다른 컴퓨터에 있으며, 나는 핑 (ping)을 통해 서로 대화 할 수 있습니다.Oracle : JMS 저장 프로 시저를 보내는 Java 저장 프로 시저

응용 프로그램 서버 내의 대기열에서 메시지를 성공적으로 가져올 수있는 Java 응용 프로그램을 만들었습니다. 애플리케이션은 JBoss v4.2.3 서버에서 실행됩니다. 원격 Java 응용 프로그램에서 JMS 메시지를 성공적으로 보낼 수 있었으므로 서버 내에서 실행중인 코드가 정상적으로 작동합니다.

작업중인 원격 Java 응용 프로그램에서 코드를 가져 와서 이것을 oracle 저장 프로 시저에 성공적으로로드했습니다. 나는 또한 loadjava 유틸리티를 사용하여 필요한 jar 파일을 oracle에로드 할 수 있었다 (나는 믿는다!). 내가로드 한 세 개의 jar 파일은 다음과 같습니다

* jms-1.1 
    * jbossmq-3.2.3 
    * jboss-client-4.0.2 

세 항아리 작업 원격 자바 응용 프로그램 내에서 사용되는 모든 필요한 것으로 나타납니다. 다음과 같이 저장 프로 시저에로드 포함 된 코드는 다음과 같습니다 나는 코드가 넘어 어디 그래서 나는 시도하고 결정할 수있는 결과 문자열을 추가 한

package com.base.jms.client; 

    import java.util.Hashtable; 

    import javax.jms.JMSException; 
    import javax.jms.Queue; 
    import javax.jms.QueueConnection; 
    import javax.jms.QueueConnectionFactory; 
    import javax.jms.QueueSender; 
    import javax.jms.QueueSession; 
    import javax.jms.TextMessage; 
    import javax.naming.Context; 
    import javax.naming.InitialContext; 

    public class StandAloneClient { 

     public static String send() throws Exception { 

      String result = "Starting -> "; 

      try { 

       Hashtable env = new Hashtable(); 
       env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); 
       env.put(Context.PROVIDER_URL, "192.168.111.242:1099"); 
       env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); 

       result = result + "Environment -> "; 

       // set up stuff 
       Context ic = new InitialContext(env); 
       result = result + "Context -> "; 

       QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ic.lookup("ConnectionFactory"); 
       result = result + "Factory -> "; 

       Queue queue = (Queue) ic.lookup("queue/A"); 
       result = result + "Queue -> "; 

       QueueConnection connection = connectionFactory.createQueueConnection(); 
       result = result + "Connection -> "; 

       QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); 
       result = result + "Session -> "; 

       QueueSender sender = session.createSender(queue); 
       connection.start(); 

       result = result + "Sender -> "; 

       TextMessage myMessage = session.createTextMessage(); 
       myMessage.setText(result); 
       sender.send(myMessage); 

       result = result + "Sending Message -> "; 

       sender.close(); 
       session.close(); 
       connection.close(); 

       result = result + "Close"; 

      } catch (JMSException e) { 
       result = result + "JMS Exception"; 

       /* 
       if(e.getMessage() != null) { 
        result = result + ":" + e.getMessage(); 
       }*/ 

      } catch (Exception e) { 
       result = result + "Exception"; 

       /* 
       if(e.getMessage() != null) { 
        result = result + ":" + e.getMessage(); 
       }*/ 

      } 

      return result; 
     } 

    } 

. 이 절차를 작성하고 테스트하기 위해, 내가 SQLPLUS에서 다음 명령을 실행 해요 :

create or replace function send_jms return VARCHAR2 as language java name 'com.base.jms.client.StandAloneClient.send() return java.lang.String'; 

variable myString varchar2(20); 
call send_jms() into :myString; 
Call completed. 
print myString; 

모든로드 할 것으로 보인다 올바르게 컴파일, 그러나 메시지가 전송되지 않습니다. 반환 된 결과 문자열은 InitialContext에서 QueueConnectionFactory 클래스를 검색 할 때 넘어지는 것을 의미합니다. 반환되는 결과 문자열은 다음과 같습니다

Starting -> Environment -> Context -> Exception 

나는이 작동하지 않는 이유에 손실에있어, 던져 예외에서 자세한 내용을 주울 수 없었습니다. 아무도 내가 이것을 올바르게하고 있음을 확인할 수 있습니까? 만약 내가 틀렸다면, 내가 뭘 잘못하고 있는지보십시오.

오래 게시물에 사과드립니다. 미리 보셔서 감사합니다!

+0

을 그냥 보조 노트로 : 오라클 고급 큐의 상단에 내장 된 JMS 구현되어 있습니다. JBoss 나 다른 응용 프로그램 서버와 함께 내장 JMS를 사용하여 공동 작업에 성공한 사람이 있습니까? Java를 사용하지 않고 PL/SQL 패키지 만 사용할 수 있습니까? – Codo

+0

JBoss에서 제공하는 Advance Queues를 사용하고 있습니다. Oracle 스트림도 JMS에 사용할 수 있습니다. 내가 한 접근 방식을 사용하는 것이 더 쉬울 것이라고 생각했습니다. 나는 다르게 생각하기 시작했습니다. :) – ScreamingMage

답변

3

필자는 오라클 데이터베이스 내에서 Java와 JMS를 실행하는 전문가는 아니지만 (세 가지 구성 요소를 각각 알고 있습니다). 그러나 귀하의 설명을 통해 Java 용 Oracle 보안 모델을 고려하지 않은 것으로 보입니다.

오라클은 명시 적으로 권한을 부여받지 않고 네트워크 (또는 파일 시스템 등)에 액세스하는 구성 요소를 허용하지 않습니다. 따라서 Oracle JVM security에 대해 읽으십시오. 원격 시스템에 연결할 수 있도록 Oracle을 구성해야하는 방법을 배우십시오. 다음 문을 포함 할 수있는 권한을 부여

: 내가 마지막으로이 모든 작업을 가지고

EXEC DBMS_JAVA.GRANT_PERMISSION('YOUR_SCHEMA', 'SYS:java.net.SocketPermission', '192.168.111.242', 'connect,accept,resolve'); 
+0

안녕하세요 코디, 응답 해 주셔서 감사합니다. 나는 당신이 JAVASYSPRIV를위한 몇가지 허가 권한들과 함께 당신이 제공 한 grant 권한을 실행했다. 문제를 따라 움직이는 것 같습니다. 이전에, 나는 당신이 말한 것과 일치하는 AccessControlException을 얻었습니다. 그러나 QueueConnectionFactory를 검색 할 때 javax.naming.CommunicationException이 발생합니다. 나는이 새로운 예외에 대한 이유를 조사 할 것이다. 당신이 제안 할 수있는 더 이상의 아이디어는 높이 평가 될 것입니다! – ScreamingMage

3

, 코디에서 제공하는 도움에 큰 부분에 감사합니다. 누군가가 같은 문제를 겪고 그 문제를 어떻게 해결했는지 알고 싶을 때를 대비해서이 답변을 올리고 있습니다.

내가 오라클에 필요한 권한을 부여 실행 명령문이었다 :

GRANT JAVASYSPRIV to NTIS 
EXEC dbms_java.grant_permission ('JAVASYSPRIV', 'SYS:java.net.SocketPermission', '*', 'accept,connect,listen,resolve'); 
EXEC DBMS_JAVA.GRANT_PERMISSION('YOUR SCHEMA', 'SYS:java.net.SocketPermission', '*', 'connect,accept,resolve'); 

당신은이 명령을 실행할 때 'SYSTEM'사용자로 기록 된해야합니다.

오라클에로드 한 라이브러리 문제로 인해 저장 프로 시저에 몇 가지 추가 문제가있었습니다. 내가 사용하는 항아리했다 :

jms 
jbossmq-client 
jboss-client 

JBossMQ와 클라이언트과 jboss-클라이언트 항아리는 애플리케이션 서버 자체에서 사용되는 것과 동일한 버전이어야합니다. JBoss 4.2.3을 사용하고 있었기 때문에 JBoss 디렉토리의 'client'폴더에서이 jar 파일을 복사했습니다.

Java 클래스/저장 프로 시저에서 참조 된 ipaddress를 hosts 파일에 넣어야 만 했으므로 oracle이 ipaddress에서 역방향 조회를 수행합니다. 이 작업을 수행하지 않으면 알 수없는 호스트 예외가 발생합니다. 호스트 파일에서 컴퓨터 이름과 ipaddress를 입력하기 만하면됩니다.

이 모든 일이 끝나면 지금은 저를 위해 올바르게 작동합니다! 같은 문제를 겪는다면이 도움이되기를 바랍니다.

0

SYS로 권한을 부여하려고했는데 정책이 SYS에 속한 경우에도 SYS에 해당 정책을 부여 할 권한이 없다는 것을 발견했습니다. 그래서 이것은 나를 위해 일한 :

exec dbms_java.grant_policy_permission('SYS','SYS','java.net.SocketPermission','*'); 
exec dbms_java.grant_permission('MY_SCHEMA', 'SYS:java.net.SocketPermission', '*', 'connect,resolve');