Closed glassfishrobot closed 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 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
Means:
Error while initializing the Sender
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 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 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 liang.x.zhao said: Hi orair,
Can you share how do you inject remote queue into local application? Thanks!
@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; (...)
/**
Obtém a fila de mensagens do servidor JNDI.
@param ctx
o contexto a ser acessado para a busca do recurso
@param senderProperties
as configurações do recurso
@return a fila de mensagens
@throws ErroDeInicializacaoDeSenderException
the erro de inicializacao de sender exception */ private Queue obtemFilaDeMensagens(Context ctx, Properties senderProperties) throws ErroDeInicializacaoDeSenderExceptionUnknown macro: { String nomeJNDI_DestinatarioDeMensagens = senderProperties.getProperty(PROPRIEDADE_NOME_JNDI_DESTINATARIO_DE_MENSAGENS); try { logger.debug("Buscando a fila JMS no servidor JNDI pelo nome <" + nomeJNDI_DestinatarioDeMensagens + ">"); return (Queue) ctx.lookup(nomeJNDI_DestinatarioDeMensagens); } catch (NamingException e) { throw new ErroDeInicializacaoDeSenderException("Erro ao inicializar Sender <" + this.getClass().getCanonicalName() + ">: problema na busca pelo nome JNDI da fila de mensagens <" + nomeJNDI_DestinatarioDeMensagens + ">.", e); } }
/**
Inicializa contexto.
@param remoteJNDIServerProperties
o(a) remote jndi server properties
@return o(a) initial context
@throws ErroDeInicializacaoDeSenderException
the erro de inicializacao de sender exception */ private InitialContext inicializaContexto(Properties remoteJNDIServerProperties) throws ErroDeInicializacaoDeSenderException { tryUnknown macro: { // Caso tenha sido obtida alguma propriedade do arquivo de configurações de conexão remota, // iniciaremos o contexto com estas configurações if (remoteJNDIServerProperties.size() > 0) { return new InitialContext(remoteJNDIServerProperties); } else { return new InitialContext(); } }
catch (NamingException e)
{ throw new ErroDeInicializacaoDeSenderException("Erro ao inicializar Sender <" + this.getClass().getCanonicalName() + ">: Falha ao obter o contexto inicial para a resolução de nomes JNDI. Configurações de conexão remota: <" + remoteJNDIServerProperties + ">", e); }
}
/**
Carrega arquivo de configurações de conexão remota da fábrica de conexões.
Este arquivo é opcional.
Note que este arquivo define as propriedades para a conexão remota para a obtenção da fábrica de conexões.
Recomenda-se que este arquivo só seja utilizado caso se queira que um cliente J2SE se conecte a um servidor JMS remoto.
No caso de clientes J2EE, recomenda-se que a fábrica de conexões seja criada no próprio servidor de aplicações, porém acessando um servidor JMS
remoto.
@return as propriedades de configurações da conexão remota para obtenção da fábrica de conexões
@throws ErroDeInicializacaoDeSenderException
the erro de inicializacao de sender exception */ private Properties carregaArquivoDeConfiguracoesDeConexaoRemotaDaFabricaDeConexoes() throws ErroDeInicializacaoDeSenderException { Properties remoteJNDIServerProperties = new Properties(); InputStream remoteServerResourceStream = null; try { remoteServerResourceStream = Loader.getResourceAsStream(getNomeArquivoPropriedadesFabricaDeConexoesDoSenderRemoteServer());
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 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 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 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 liang.x.zhao said: This defect is duplicate to #6885. It will be followed up with 6885.
@glassfishrobot Commented File: EtlCvmRad.etlCvm-enet-extracao-escalonador-EscalonadorDeDespachantesEmpresasNet.geral.debug.log Attached By: orair
@glassfishrobot Commented File: NetBeansProjects.zip Attached By: liang.x.zhao
@glassfishrobot Commented Was assigned to liang.x.zhao
@glassfishrobot Commented This issue was imported from java.net JIRA GLASSFISH-18498
@glassfishrobot Commented Reported by orair
@glassfishrobot Commented Marked as duplicate on Tuesday, May 15th 2012, 7:29:14 pm
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]