eclipse-ee4j / glassfish

Eclipse GlassFish
https://eclipse-ee4j.github.io/glassfish/
386 stars 144 forks source link

Failing to get JMS Queue using explicit remote JNDI lookup #18498

Closed glassfishrobot closed 12 years ago

glassfishrobot commented 12 years ago

I've used to create to domains: domain1, domain2. Some applications inside domain2 used to get a JMS queue resource using explicit remote JNDI lookup to the domain1 JNDI server.

It used to work using Glassfish 3.1.1 to deploy app1 on domain1 and app2 to domain2.

Now, I've started to migrate from Glassfish 3.1.1 to Glassfish 3.1.2.

The app2 inside domains2 using glassfish 3.1.1 cannot get a remote Queue anymore from domain1 using glassfish 3.1.2.

Stack trace attached.

Environment

Glassfish 3.1.1 Glassfish 3.1.2

Affected Versions

[3.1.2]

glassfishrobot commented 6 years ago
glassfishrobot commented 12 years ago

@glassfishrobot Commented liang.x.zhao said: orair:

Could you please provide simple sample codes for reproduction? And could you please also provide the stack trace in English?

glassfishrobot commented 12 years ago

@glassfishrobot Commented orair said: Zhao,

The stack trace is in English. Just the business error message is in portuguese. The message: DespachanteDeMensagens.java:190 - Falha na criação do Sender de Relatórios CVM - RAD. econoinfo.client.sender.exception.ErroDeInicializacaoDeSenderException: Erro ao inicializar Sender : problema na busca pelo nome JNDI da fila de mensagens <jms/isef_cvm>. at econoinfo.client.sender.AbstractSenderAppService_JMS.obtemFilaDeMensagens(AbstractSenderAppService_JMS.java:440) ~[despachante-common-0.2-SNAPSHOT.jar:na]

Means: Error while initializing the Sender : problems while looking up the resource JNDI name of the JMS queue <jms/isef_cvm>.

My code just read from a properties file both the InitialHost (specifying the JNDI server to be connected) and the JNDI name to be lookup up (explicitly). So it just try to get the JMS Queue using a explicit JNDI lookup.

To reproduce the problem you need follow these steps: 1 - Start domain1 in Glassfish 3.1.2. 2 - Create a JMS Queue (in my case named jms/isef_cvm) 3 - Create a domain2 using different ports (in my case portbase 18000) 4 - Deploy any application in domain2 that try to get the JMS Queue using explicit JNDI lookup accessing the JNDI server from domain1 (by default accessing port 3700).

If you really need a test case, please tell me and I will create a separate app that performs these simple steps.

Br, Orair.

glassfishrobot commented 12 years ago

@glassfishrobot Commented liang.x.zhao said: If you are looking up the remote JMS Connection Factory from within server, then you will get javax.naming.NameNotFoundException, which is a known issue. #6885 was filed for that. But the remote JMS queue can be looked up from within server.

Following to your test case, the workaround could be:

1. Create JMS queue in domain1::server1. 2. In domain2::server2, Create JMS Connection Factory with addressList property pointing to mq of server1 (for example, 7676 is the JMS port of server1). asadmin create-jms-resource --port 6048 --restype javax.jms.ConnectionFactory --property "AddressList=localhost\:7676" jms/SenderFactory 3. In the EJB which is deployed in server2, look up jms/SenderFactory from local(server2) JNDI tree, and look up JMS queue from server1's JNDI tree. 4. Then you can send jms messages to the remote queue successfully.

Let me know if it works for you.

glassfishrobot commented 12 years ago

@glassfishrobot Commented orair said: Hi David Zhao, I already created the JMS Connection Factory in domain2 and pointed to mq to server1. I didn't describe these steps because they are not neeeded, since the app is failing when trying to inject the JMS Queue. I've googled for the stack trace and it indicates that the com.sun.enterprise.resource.beans.AdministeredObjectResource cannot be serialized and injected anymore. It would be a ClassLoader issue too, but it is consistent and keeps failing after a Glassfish restarts.

org.omg.CORBA.NO_IMPLEMENT: WARNING: IOP01000001: Missing local value implementation vmcid: SUN minor code: 1 completed: Maybe at sun.reflect.GeneratedConstructorAccessor289.newInstance(Unknown Source) (...) Caused by: java.lang.ClassNotFoundException: com.sun.enterprise.resource.beans.AdministeredObjectResource (no security manager: RMI class loader disabled)

Br, Orair.

glassfishrobot commented 12 years ago

@glassfishrobot Commented liang.x.zhao said: Hi orair,

Can you share how do you inject remote queue into local application? Thanks!

glassfishrobot commented 12 years ago

@glassfishrobot Commented orair said: Hi Zhao, I just construct the Context using InitialContext(Properties): if (remoteJNDIServerProperties.size() > 0)

{ return new InitialContext(remoteJNDIServerProperties); }

else

{ return new InitialContext(); }

After I get the queue calling ctx.lookup(String queueName): return (Queue) ctx.lookup(nomeJNDI_DestinatarioDeMensagens);

Our relevant code are: 1 - function to load configuration (Properties) from a .properties file called carregaArquivoDeConfiguracoesDeConexaoRemotaDaFabricaDeConexoes (may be translated to loadRemoteConnectionConfiguration) 2 - function to create the context based on the Properties found inside .properties file called inicializaContexto (may be translated to initializeContext) 3 - function to get the queue using explicit JNDI lookup called obtemFilaDeMensagens (may be translated to getMessageQueue)

Source Code: (...) public void init() throws ErroDeInicializacaoDeSenderException { (...) Context contextoDaFilaDeMensagens;

// Carrega o arquivo com as configurações a um servidor JNDI remoto para obtenção da fila de mensagens Properties propriedadesParaAcessoRemotoAFilaDeMensagens = carregaArquivoDeConfiguracoesDeConexaoRemotaDaFilaDeMensagens();

// Inicializa o contexto para obter a fábrica de conexões contextoDaFilaDeMensagens = inicializaContexto(propriedadesParaAcessoRemotoAFilaDeMensagens);

// Obtém a fila de mensagens do servidor JNDI this.filaDeMensagens = obtemFilaDeMensagens(contextoDaFilaDeMensagens, senderProperties);

// Marca o Sender como inicializado this.senderInicializado = true; (...)

/**

/**

/**

if (remoteServerResourceStream != null) { logger.debug("Encontrou configurações para o acesso remoto à fábrica de conexões no arquivo <"

{ logger.debug("Iniciando o contexto para a obtenção do nome JNDI da fábrica de conexões com as configurações: " + remoteJNDIServerProperties); }

else

{ logger.debug("Não encontrou propriedades com configurações para o acesso remoto à fábrica de conexões no arquivo <" + getNomeArquivoPropriedadesFabricaDeConexoesDoSenderRemoteServer() + ">. Será realizado o acesso com as configurações padrão."); }

} else

{ logger.debug("Não encontrou configurações para o acesso remoto à fábrica de conexões no arquivo <" + getNomeArquivoPropriedadesFabricaDeConexoesDoSenderRemoteServer() + ">. Será realizado o acesso com as configurações padrão."); }

} catch (FileNotFoundException e)

{ logger.warn("Arquivo de configurações para o acesso remoto à fábrica de conexões não encontrado. Arquivo procurado <" + getNomeArquivoPropriedadesFabricaDeConexoesDoSenderRemoteServer() + ">. As configurações de conexão remota serão ignoradas...", e); }

catch (IOException e)

{ logger.warn("Problemas de leitura no arquivo de configurações de conexão remota à fábrica de conexões. Arquivo procurado <" + getNomeArquivoPropriedadesFabricaDeConexoesDoSenderRemoteServer() + ">. As configurações de conexão remota serão ignoradas...", e); }

finally

{ IOUtils.closeQuietly(remoteServerResourceStream); }

return remoteJNDIServerProperties; }

BR,

Orair.

glassfishrobot commented 12 years ago

@glassfishrobot Commented liang.x.zhao said: Hi orair,

I don't know why you failed in looking up remote queue at your side. But it works for me in my test. I would like sharing my test case with you:

1. Suppose the default domain1 with all default configurations was already there after GlassFish installation. 2. Create a new domain jms-sender. asadmin create-domain --user=admin --portbase 6000 jms-sender Then you will get the following ports: Using port 6048 for Admin. Using port 6080 for HTTP Instance. Using port 6076 for JMS. Using port 6037 for IIOP. Using port 6081 for HTTP_SSL. Using port 6038 for IIOP_SSL. Using port 6039 for IIOP_MUTUALAUTH. Using port 6086 for JMX_ADMIN. Using port 6066 for OSGI_SHELL. Using port 6009 for JAVA_DEBUGGER. 3. Start domains. asadmin start-domain domain1 asadmin start-domain jms-sender 4. Create jms resources on different domains. asadmin create-jms-resource --user admin --port 4848 --target server --restype javax.jms.Queue --property imqDestinationName=isef_cvm jms/isef_cvm asadmin create-jms-resource --user admin --port 6048 --restype javax.jms.ConnectionFactory --property "AddressList=localhost\:7676" jms/SenderFactory 5. Unzip the attached file NetBeansProjects.zip. 6. Deploy "NetBeansProjects\receiver-mdb\dist\receiver-mdb.jar" to domain1. 7. Deploy "NetBeansProjects\jms-sender\dist\jms-sender.ear" to jms-sender. 8. Open browser, input url "http://localhost:6080/jms-sender-war/jmsServlet" and press Enter button. 9. Check the server.log files of both domain1 and jms-sender. a) In server.log of jms-sender, it shows both queue and ConnectionFactory are got. [#|2012-03-14T15:09:13.473+0800|INFO|glassfish3.1.2|test.sender.SenderEjb|_ThreadID=27;_ThreadName=Thread-2;|Queue: Oracle GlassFish(tm) Server MQ Destination getName(): isef_cvm Class: com.sun.messaging.Queue getVERSION(): 3.0 isReadonly(): false getProperties():

{imqDestinationName=isef_cvm, imqDestinationDescription=A Description for the Destination Object}

|#]

[#|2012-03-14T15:09:13.474+0800|INFO|glassfish3.1.2|test.sender.SenderEjb|_ThreadID=27;_ThreadName=Thread-2;|CF: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@2ff9fa|#]

b) In server.log of domain1, it shows the jms message sent to the queue is received by MDB, [#|2012-03-14T15:09:13.485+0800|INFO|glassfish3.1.2|test.receiver.NewMessageBean|_ThreadID=22;_ThreadName=Thread-2;|Received message: Hello World!!! Wed Mar 14 15:09:13 CST 2012|#]

Note: If your domain1 is security enabled, please uncomment the username/password setting lines in SenderEJB.java for that.

Please check the source codes of SenderEjb.java for the details on how it looks up the remote queue and local ConnectionFactory via JNDI, let me know if you have further questions.

glassfishrobot commented 12 years ago

@glassfishrobot Commented liang.x.zhao said: Hi orair,

Could you confirm if you had a chance to try my demo projects? Does it work for you?

glassfishrobot commented 12 years ago

@glassfishrobot Commented orair said: Unfortunatelly I couldn't test it yet, because a lot of deadlines. Sorry.

I will test it as soon as possible.

Br, Orair.

glassfishrobot commented 12 years ago

@glassfishrobot Commented liang.x.zhao said: This defect is duplicate to #6885. It will be followed up with 6885.

glassfishrobot commented 12 years ago

@glassfishrobot Commented File: EtlCvmRad.etlCvm-enet-extracao-escalonador-EscalonadorDeDespachantesEmpresasNet.geral.debug.log Attached By: orair

glassfishrobot commented 12 years ago

@glassfishrobot Commented File: NetBeansProjects.zip Attached By: liang.x.zhao

glassfishrobot commented 12 years ago

@glassfishrobot Commented Was assigned to liang.x.zhao

glassfishrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA GLASSFISH-18498

glassfishrobot commented 12 years ago

@glassfishrobot Commented Reported by orair

glassfishrobot commented 12 years ago

@glassfishrobot Commented Marked as duplicate on Tuesday, May 15th 2012, 7:29:14 pm