usar stored procedimientos procedimiento preparecall llamar funcion ejemplo ejecutar desde como callablestatement almacenados almacenado java oracle jboss jms

stored - Oracle: procedimiento almacenado Java que envía mensaje JMS



procedimiento almacenado spring (3)

Estoy intentando enviar un mensaje JMS punto a punto desde un procedimiento almacenado de la base de datos de Oracle a una aplicación Java. Los dos "puntos" se encuentran en diferentes máquinas, que he confirmado que pueden comunicarse entre sí a través de ping.

Creé una aplicación Java capaz de eliminar mensajes de una cola dentro del servidor de aplicaciones. La aplicación se ejecuta dentro de un servidor JBoss v4.2.3. Pude enviar con éxito un mensaje JMS desde una aplicación Java remota, por lo que estoy seguro de que el código que se ejecuta dentro del servidor es correcto.

Tomé el código de la aplicación Java remota en funcionamiento y lo cargué con éxito en un procedimiento almacenado de Oracle. También he logrado (¡creo!) Cargar en Oracle los archivos jar requeridos usando la utilidad loadjava. Los tres archivos jar que he cargado son:

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

Los tres frascos se utilizan dentro de la aplicación java remota activa y parecen ser todo lo que se necesita. El código contenido cargado en el procedimiento almacenado es el siguiente:

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

He agregado la cadena de resultados para poder intentar determinar en qué parte del código se está cayendo. Para crear y probar este procedimiento, estoy ejecutando los siguientes comandos en 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;

Todo parece estar cargado y compilando correctamente, sin embargo, el mensaje no se envía. La cadena de resultado devuelta implica que se está cayendo al intentar recuperar la clase QueueConnectionFactory del InitialContext. La cadena de resultado devuelta es:

Starting -> Environment -> Context -> Exception

No entiendo por qué esto no funciona, y no he podido obtener más de la Excepción lanzada. ¿Alguien puede confirmar que estoy haciendo esto correctamente, y si lo estoy, ver lo que estoy haciendo mal?

Disculpas por el largo plazo pero gracias de antemano por mirarlo!


Descubrí que, aunque intentaba otorgar el permiso como SYS, y la política pertenecía a SYS, entonces SYS no tenía permiso para otorgar esa política. Así que esto funcionó para mí:

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


Finalmente conseguí que todo funcionara, gracias en gran parte a la ayuda ofrecida por Cody. Solo estoy respondiendo por si alguien más se encuentra con los mismos problemas y quiere saber exactamente cómo lo resolví.

Las declaraciones que ejecuté para otorgar los permisos necesarios al oráculo fueron:

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

Debe iniciar sesión como usuario ''SISTEMA'' al ejecutar estos comandos.

Tuve algunos problemas adicionales con el procedimiento almacenado que se debieron a problemas con las bibliotecas que cargué en el oráculo. Los frascos que utilicé fueron:

jms jbossmq-client jboss-client

Los jbossmq-client y jboss-client jars deben tener las mismas versiones que los utilizados en el servidor de aplicaciones. Estaba usando JBoss 4.2.3, así que copié estos archivos jar de la carpeta ''cliente'' dentro del directorio de JBoss.

También tuve que poner el direccionamiento ipaddress en la clase java / procedimiento almacenado en el archivo de hosts, ya que parece que Oracle hace una búsqueda inversa en el ipaddress. Si no lo haces, obtienes una excepción de host desconocido. En el archivo hosts, solo ingrese el nombre de su computadora y la dirección IP.

¡Después de hacer todo esto, ahora está funcionando correctamente para mí! Espero que esto ayude a alguien si encuentran el mismo problema.


No soy exactamente un experto en ejecutar Java y JMS dentro de la base de datos Oracle (aunque conozco cada uno de los tres componentes por separado). Pero según su descripción, parece que no ha tenido en cuenta el modelo de seguridad de Oracle para Java.

Oracle no permitirá que ningún componente acceda a la red (o al sistema de archivos, etc.) sin que se le haya otorgado explícitamente el derecho a. Así que comience a leer sobre la seguridad de Oracle JVM para saber cómo puede necesitar configurar Oracle para que pueda conectarse a una máquina remota.

Conceder los permisos podría implicar la siguiente declaración:

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