Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle:Java存储过程发送JMS消息_Java_Oracle_Jboss_Jms - Fatal编程技术网

Oracle:Java存储过程发送JMS消息

Oracle:Java存储过程发送JMS消息,java,oracle,jboss,jms,Java,Oracle,Jboss,Jms,我试图从oracle数据库存储过程向java应用程序发送点对点JMS消息。这两个“点”位于不同的机器上,我已经确认它们可以通过ping相互通信 我已经创建了一个java应用程序,它能够成功地将消息从应用程序服务器中的队列中移除。该应用程序正在JBoss v4.2.3服务器中运行。我已经能够成功地从远程java应用程序发送JMS消息,因此我确信服务器中运行的代码是正常的 我从正在工作的远程java应用程序中获取了代码,并成功地将其加载到oracle存储过程中。我还设法(我相信!)使用loadjav

我试图从oracle数据库存储过程向java应用程序发送点对点JMS消息。这两个“点”位于不同的机器上,我已经确认它们可以通过ping相互通信

我已经创建了一个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
这三个JAR在工作的远程java应用程序中使用,似乎是所需的全部。加载到存储过程中的代码如下所示:

    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
我不知道这为什么不起作用,并且无法从抛出的异常中收集更多信息。有人能确认我做得对吗?如果是的话,看看我做错了什么


为这篇冗长的帖子道歉,但提前感谢您的关注

我并不是在Oracle数据库中运行Java和JMS的专家(尽管我分别了解这三个组件)。但是从您的描述来看,您似乎没有考虑到针对Java的Oracle安全模型

在未明确获得访问权限的情况下,Oracle不会允许任何组件访问网络(或文件系统等)。因此,请开始阅读以下内容,了解您可能需要如何配置Oracle以便连接到远程计算机

授予权限可能涉及以下语句:

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

我终于把这一切都做好了,这在很大程度上要感谢科迪提供的帮助。我只是把这个答案贴出来,以防其他人遇到同样的问题,想知道我是如何解决的

我为向oracle授予必要权限而运行的语句有:

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');
执行这些命令时,您必须以“系统”用户身份登录

我在存储过程方面还有一些问题,这是由于我加载到oracle中的库的问题。我使用的罐子是:

 jms
 jbossmq-client 
 jboss-client 
jbossmq客户端和jboss客户端JAR的版本必须与应用服务器本身中使用的版本相同。我使用的是JBoss4.2.3,所以我从JBoss目录中的“client”文件夹复制了这些JAR

我还必须将java类/存储过程中引用的ipaddress放在hosts文件中,因为oracle似乎对ipaddress进行了反向查找。如果不这样做,则会出现未知主机异常。在hosts文件中,只需输入您的计算机名和IP地址


在完成所有这些之后,它现在对我来说正常工作了!希望这对遇到同样问题的人有所帮助。

我发现,即使我尝试以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' );

正如旁注:Oracle附带了一个构建在高级排队之上的JMS实现。有没有人使用内置JMS成功地与JBoss或其他应用程序服务器进行互操作,甚至可能不使用Java,而只是使用PL/SQL包?我已经使用JBoss提供的Advanced队列进行了研究。Oracle streams也可用于JMS。我认为采用我所做的方法会更容易。我开始不这么想了:)嗨,科迪,谢谢你的回复。我已经运行了您提供的grant权限,以及对JAVASYSPRIV的几个grant权限,用于我正在使用的模式。这似乎解决了这个问题。之前,我得到了一个AccessControlException,它与您所说的一致。但是,现在我在尝试检索QueueConnectionFactory时遇到了javax.naming.CommunicationException。我将调查此新异常的原因。如果您有任何进一步的想法,我们将不胜感激!