【发布时间】:2014-06-21 18:06:50
【问题描述】:
我已将 custom jndi-resource factory 添加到我的 tomcat(嵌入式 hornetq 的 ConnectionFactory 的 jndi 资源)。我的资源需要一些配置文件;我把它们放在${catalina_home}/hornetq 文件夹中。我有一个在 tomcat 启动中使用此资源的测试网络应用程序。在tomcat启动中,当test-web-app想要使用我的资源时,资源想要锁定配置文件但它不能,它会抛出`OverlappingFileLockException:
java.nio.channels.OverlappingFileLockException
at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255)
at sun.nio.ch.SharedFileLockTable.add(FileLockTable.java:152)
at sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:1056)
at org.hornetq.core.server.impl.FileLockNodeManager.tryLock(FileLockNodeManager.java:266)
at org.hornetq.core.server.impl.FileLockNodeManager.isBackupLive(FileLockNodeManager.java:82)
at org.hornetq.core.server.impl.HornetQServerImpl$SharedStoreLiveActivation.run(HornetQServerImpl.java:2161)
at org.hornetq.core.server.impl.HornetQServerImpl.start(HornetQServerImpl.java:450)
at org.hornetq.jms.server.impl.JMSServerManagerImpl.start(JMSServerManagerImpl.java:485)
at org.hornetq.jms.server.embedded.EmbeddedJMS.start(EmbeddedJMS.java:115)
at ...
是否可以在 tomcat 或 OS 中禁用文件锁定(${catalina_home}/hornetq 目录中的文件)?
更新:
我在 tomcat 中 context.xml 文件中的 jndi-resource(名称为:/ConnectionFactory 的连接工厂在 hornetq-jms.xml 中定义):
<Resource name="jms/ConnectionFactory" auth="Container"
type="javax.jms.ConnectionFactory"
factory="com.wise.jms.hornetq.embedded.HornetqConnectionFactoryBuilder"
cf-name="/ConnectionFactory" singletone="true"/>
我的工厂班:HornetqConnectionFactoryBuilder。我把包含这个类的jar放到${catalina_home}/lib目录下(嵌入的hornetq会在第一个getObjectInstance方法调用中启动):
public class HornetqConnectionFactoryBuilder implements ObjectFactory{
private EmbeddedJMS embeddedJMS;
private static final String ConnectionFactoryName = "cf-name";
private static final String HornetqConfigDirectoryPath = getCatalinaHomePath() + "/conf/hornetq/";
private static final String JmsConfigFilePath = HornetqConfigDirectoryPath + "hornetq-jms.xml";
private static final String HornetqConfigFilePath = HornetqConfigDirectoryPath + "hornetq-configuration.xml";
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception{
Properties properties = initProperties((Reference) obj);
validateProperties(properties);
initHornetq();
String connectionFactoryJndiName = (String) properties.get(ConnectionFactoryName);
return embeddedJMS.lookup(connectionFactoryJndiName);
}
private synchronized void initHornetq() throws Exception{
if (embeddedJMS == null){
embeddedJMS = new EmbeddedJMS();
embeddedJMS.setJmsConfigResourcePath(JmsConfigFilePath);
embeddedJMS.setConfigResourcePath(HornetqConfigFilePath);
embeddedJMS.start();
}
}
private Properties initProperties(Reference reference) throws IOException{
Enumeration<RefAddr> addresses = reference.getAll();
Properties properties = new Properties();
while (addresses.hasMoreElements()) {
RefAddr address = addresses.nextElement();
String type = address.getType();
String value = (String) address.getContent();
properties.put(type, value);
}
return properties;
}
private void validateProperties(Properties properties){
validateSingleProperty(properties, ConnectionFactoryName);
}
private static String getCatalinaHomePath(){
String catalinaHome = System.getenv("CATALINA_HOME");
if (catalinaHome == null){
throw new IllegalArgumentException("CATALINA_HOME environment variable should be set");
}
return "file:///" + catalinaHome.replaceAll("\\\\", "/");
}
private static void validateSingleProperty(Properties properties, String propertyName){
if (!properties.containsKey(propertyName)){
throw new IllegalArgumentException(propertyName + " property should be set.");
}
}
}
我的 test-web-app Test Class(测试方法将在 test-web-app 启动时午餐):
public class Test{
private ConnectionFactory connectionFactory;
public Test() throws NamingException{
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
connectionFactory = (ConnectionFactory) envCtx.lookup("jms/ConnectionFactory");
}
public void test() throws JMSException{
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(true,Session.SESSION_TRANSACTED);
Queue queue = session.createQueue("testQueue");
MessageProducer messageProducer = session.createProducer(queue);
MessageConsumer messageConsumer = session.createConsumer(queue);
TextMessage message1 = session.createTextMessage("This is a text message1");
messageProducer.send(message1);
session.commit();
TextMessage receivedMessage = (TextMessage) messageConsumer.receive(5000);
session.commit();
System.out.println("Message1 received after receive commit: " + receivedMessage.getText());
}
public void setConnectionFactory(ConnectionFactory connectionFactory){
this.connectionFactory = connectionFactory;
}
}
注意:当我将 (hornetq) 配置文件放入 jar 类路径时,我没有问题,一切都很好!! (tomcat: 6, hornetq: 2.4.0.Final, OS: windows 7)
【问题讨论】:
-
HornetQ 没有为 Tomcat 编写集成...所以我不确定您是如何集成到 Tomcat 的,因此您的集成中会缺少其他内容。我建议您提供更多信息,以便我们为您提供帮助。也许你应该创建一个 HornetQ 用户论坛,在这里我们可以做更多的讨论风格,看看你做错了什么。
-
我更新了我的问题。