Como eu escrevo um Java EE / EJB Singleton?
Um dia atrás, meu aplicativo era um EAR, contendo um WAR, um EJB JAR e alguns arquivos JAR utilitários. Eu tinha uma classe singleton POJO em um desses arquivos utilitários, funcionava e tudo estava bem com o mundo:
EAR
|--- WAR
|--- EJB JAR
|--- Util 1 JAR
|--- Util 2 JAR
|--- etc.
Então, criei um segundo WAR e descobri (da maneira mais difícil) que cada WAR possui seu próprio ClassLoader, de modo que cada WAR vê um singleton diferente e as coisas se deterioram a partir daí. Isso não é tão bom.
EAR
|--- WAR 1
|--- WAR 2
|--- EJB JAR
|--- Util 1 JAR
|--- Util 2 JAR
|--- etc.
Então, estou procurando uma maneira de criar um objeto Java singl, eton que funcione em WARs (em ClassLoaders?). o@Singleton
A anotação do EJB parecia bastante promissora até que eu descobri que o JBoss 5.1 não parece suportar essa anotação (que foi adicionada como parte do EJB 3.1). Perdi alguma coisa - posso usar@Singleton
com o JBoss 5.1? Atualizar para o JBoss AS 6 não é uma opção no momento.
Como alternativa, eu ficaria feliz em não precisar usar o EJB para implementar meu singleton. O que mais posso fazer para resolver este problema? Basicamente, eu preciso de um gancho * semi-amplo para aplicativos em vários outros objetos, como vários dados em cache e informações de configuração de aplicativos. Como último recurso, eu já considerei mesclar minhas duas WARs em uma, mas isso seria bem infernal.
* Significado: disponível basicamente em qualquer lugar acima de uma determinada camada; por enquanto, principalmente em meus WARs - o View and Controller (em um sentido genérico).
Editar: Eu realmente deveria estar chamandoJava EE ao invés de J2EE, não devo?
Edição 2: Muito obrigado novamente a @Yishai por toda a ajuda. Após algumas tentativas e erros, parece que eu descobri como usar um único ClassLoader em WARs no JBoss 5. Estou detalhando isso abaixo por minha própria conta, e espero que outros achem isso útil também.
N.B. isso é bastante diferente de fazer isso no JBoss 4 (veja a resposta de Yishai ou meus links abaixo).
Em vez de escrever umjboss-web.xml
para cada WAR e umjboss.xml
para o ouvido EJB-JAR, coloque umjboss-classloading.xml
em cada WAR, no mesmo local que o DD (web.xml
) O conteúdo dejboss-classloading.xml
deveria estar:
<?xml version="1.0" encoding="UTF-8"?>
<classloading
xmlns="urn:jboss:classloading:1.0"
name="mywar.war"
domain="DefaultDomain"
parent-domain="Ignored"
export-all="NON_EMPTY"
import-all="true">
</classloading>
Isto segue do JBoss CWaqui, enquanto o que (acho) funciona para o JBoss 4.x é descritoaqui. Informações mais gerais sobre o JBoss classload (ing / ers):
visão globalHistóriaCasos de usoO melhor que posso dizer é que os documentos wiki da comunidade JBoss faltam para o JBoss 5 em comparação com o JBoss 4.