2011-08-09 23 views
5

Próbuję wysłać wiadomość JMS Point-to-Point z procedury składowanej bazy danych Oracle do aplikacji Java. Te dwa punkty znajdują się na różnych komputerach, które, jak potwierdziłem, mogą komunikować się ze sobą za pomocą polecenia ping.Oracle: procedura składowana Java wysyłająca wiadomość JMS

Utworzyłem aplikację Java, która może skutecznie odbierać wiadomości z kolejki na serwerze aplikacji. Aplikacja działa na serwerze JBoss v4.2.3. Udało mi się wysłać wiadomość JMS ze zdalnej aplikacji java, więc jestem pewien, że kod działający na serwerze jest w porządku.

Pobrałem kod z działającej aplikacji zdalnej java i załadowałem ją pomyślnie do przechowywanej procedury oracle. Udało mi się również (jak sądzę!) Załadować do oracle wymagane pliki jar za pomocą narzędzia loadjava. Te trzy pliki jar mam załadowane są:

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

trzy słoiki są wykorzystywane w pracy zdalnej aplikacji Java i wydaje się być wszystko, co wymagane. Kod zawarty załadowany do procedury przechowywanej jest następujący:

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; 
     } 

    } 

Dodałem ciąg wynik w tak mogę spróbować określić, gdzie w kodzie to wypadnięciu. Aby utworzyć i przetestować tę procedurę, jestem wykonywania następujących poleceń w 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; 

Wszystko wydaje się być załadowana i kompilowanie prawidłowo, jednak wiadomość nie jest wysyłana. Zwracany ciąg wyniku implikuje, że jest on przewracany podczas próby pobrania klasy QueueConnectionFactory z InitialContext. Ciąg wynik zwracany jest:

Starting -> Environment -> Context -> Exception 

Jestem w rozterce, dlaczego to nie działa, i nie byli w stanie zebrać więcej z wyjątku rzucony. Czy ktoś może potwierdzić, że robię to poprawnie, a jeśli tak, to co robię źle?

Przepraszam za długi wpis, ale z góry dziękuję za obejrzenie go!

+0

Podobnie jak marginesie: Oracle pochodzi z realizacji JMS zbudowany na szczycie Advanced Queuing. Czy kiedykolwiek udało się współpracować z JBoss lub innym serwerem aplikacji przy użyciu wbudowanego JMS, prawdopodobnie nawet nie używając Java, ale tylko pakiety PL/SQL? – Codo

+0

Miałem wygląd przy użyciu Advance Queues oferowanych przez JBoss. Strumienie Oracle można również wykorzystać w JMS. Myślałem, że łatwiej będzie zastosować podejście, które zrobiłem. Zaczynam myśleć inaczej :) – ScreamingMage

Odpowiedz

3

Nie jestem ekspertem od uruchamiania Javy i JMS w bazie danych Oracle (choć znam każdy z tych trzech składników osobno). Ale z twojego opisu wynika, że ​​nie wziąłeś pod uwagę modelu zabezpieczeń Oracle dla Javy.

Oracle nie pozwoli żadnemu komponentowi uzyskać dostępu do sieci (lub systemu plików itp.) Bez wyraźnego przyznania mu prawa. Więc zacznij czytać o Oracle JVM security, aby dowiedzieć się, jak skonfigurować Oracle, aby umożliwić połączenie ze zdalnym komputerem.

Nadawanie uprawnień może obejmować następujące oświadczenie:

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

Cześć Cody, dzięki za odpowiedź. Uruchomiłem to uprawnienie do udzielania zgody, które podałeś wraz z kilkoma uprawnieniami do przyznawania uprawnień dla JAVASYSPRIV, dla schematu, przeciwko któremu pracuję. Wygląda na to, że poruszyło to problem. Poprzednio otrzymywałem wyjątek AccessControlException, który jest zgodny z tym, co powiedziałeś. Jednak teraz otrzymuję wyjątek javax.naming.CommunicationException podczas próby pobrania obiektu QueueConnectionFactory. Zbadam przyczynę tego nowego wyjątku. Wszelkie dodatkowe pomysły, które możesz zaoferować, zostaną docenione! – ScreamingMage

3

mam w końcu dostał to wszystko działa, dzięki w dużej mierze przy pomocy oferowanej przez Cody. Po prostu podaję tę odpowiedź, na wypadek, gdyby ktoś inny natknął się na te same problemy i chce dokładnie wiedzieć, jak to rozwiązałem.

Sprawozdania Pobiegłem do udzielenia niezbędnych uprawnień do wyroczni były:

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'); 

Trzeba został zalogowany jako „system” użytkownikowi podczas wykonywania tych poleceń.

Miałem kilka dalszych problemów z procedurą składowaną, które były spowodowane problemami z bibliotekami, które załadowałem do oracle. Słoiki I były:

jms 
jbossmq-client 
jboss-client 

jbossmq-klient i słoiki JBoss-klienckie muszą być takie same jak te używane wersje w samym serwerze aplikacji. Używałem JBoss 4.2.3, więc skopiowałem te słoiki z folderu "klient" w katalogu JBoss.

Musiałem również wstawić adres ipaddress w klasie java/procedura przechowywana w pliku hosts, ponieważ wygląda na to, że oracle wykonuje odwrotne wyszukiwanie na ipaddress. Jeśli tego nie zrobisz, otrzymasz wyjątek od nieznanego hosta. W pliku hosts po prostu wpisz nazwę komputera i adres ipaddress.

Po wykonaniu wszystkich tych czynności, teraz działa poprawnie dla mnie! Mam nadzieję, że to pomoże komuś, kto spotka się z tym samym problemem.

0

Znalazłem, że chociaż próbowałem nadać uprawnienia jako SYS, a zasada należała do SYS, to SYS nie ma uprawnień do przyznania tej zasady. Więc ten pracował dla mnie:

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