我正在尝试从 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 JVM security了解您可能需要如何配置 Oracle 才能连接到远程计算机。
授予权限可能涉及以下语句:
EXEC DBMS_JAVA.GRANT_PERMISSION('YOUR_SCHEMA', 'SYS:java.net.SocketPermission', '192.168.111.242', 'connect,accept,resolve');
关于java - Oracle:Java 存储过程发送 JMS 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7000003/