Pergunta

Eu tenho um EJB singleton que está sendo inicializado duas vezes. Não tenho idéia do porquê e está definindo completamente o ponto de ter um feijão de singleton, tanto quanto eu sei. Qualquer ajuda será apreciada. Como você pode ver, tentei colocar um booleano estático para impedir a inicialização múltipla (não que deve ser necessária), mas não fez diferença.

Feijão:

@Singleton 
@Startup
public class DataModelBean implements DataModelBeanLocal {

   private static Logger log = Logger.getLogger(DataModelBean.class.getName());

   @PostConstruct
   public void init(){
      log.info(this);           
   }
}

Snippet de saída de log:

2010-02-17 16:06:13,670 INFO  [AutoDeployer        :DataModelBean       ] com.xxx.xxx.datamodel.DataModelBean@117843d
2010-02-17 16:06:14,233 INFO  [AutoDeployer        :DataModelBean       ] com.xxx.xxx.datamodel.DataModelBean@62b9d3

Está criando 2 feijão !! Ou está implantando o aplicativo duas vezes?

Como um aparte, estou usando o Glassfish V3, isso é maduro o suficiente? Devo usar V2 ou algo mais? Pensamentos?

Foi útil?

Solução

O seguinte singleton:

@Singleton
public class MasterDataCache 
{
    private final static Logger logger = LoggerFactory.getLogger(MasterDataCache.class);

    private Map cache;

    @PostConstruct
    public void initCache() {
        logger.debug("initCache()");
        this.cache = new HashMap();
    }

    public Object get(String key){
        return this.cache.get(key);
    }

    public void store(String key,Object value){
        this.cache.put(key, value);
    }
}

E o seguinte servlet:

@WebServlet(name="SingletonTester", urlPatterns={"/SingletonTester"})
public class SingletonTester extends HttpServlet {

    @EJB
    MasterDataCache masterDataCache;

    @Override
    public void init(){
     masterDataCache.store("startup", new Date());
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        try {
            out.println("Startup time: " + masterDataCache.get("startup") );
        } finally {
            out.close();
        }
    }
}

A embalada como uma guerra funciona conforme o esperado quando implantado "manualmente" em GFV3. Ele também implanta bem e funciona como esperado em Netbeans (o initCache é chamado apenas uma vez). Meu único problema é que a implantação falha no Eclipse (GFV3 reclama eclipseApps/$projectName não contendo nenhum módulo EJB, que está no entanto eclipseApps/$projectName/WEB-INF/classses). Infelizmente, isso parece ser um bug com o plug -in Glassfish Eclipse (pelo menos a versão que estou usando). No entanto, não vejo muitos problemas no rastreador de questões ... estranho, porque isso parece um grande bloqueio. Mas fora do eclipse, o GFV3 se comporta normalmente, eu não conseguia reproduzir seu problema.

Atualizar: Finalmente consegui as coisas funcionando com o Eclipse e Glassfish V3. Não vou dar todos os detalhes, mas o problema é que, de alguma forma, não consegui obter meu projeto diretamente reconhecido como um "módulo dinâmico da web" 2.5, a versão foi definida como 2.3 e acho que isso teve algo a ver com o erro de implantação no GFV3. Depois de configurar meu projeto corretamente (com uma faceta definida como 2.5), implantá -lo funcionou bem. Então eu apenas me estraguei.

Outras dicas

Este problema acontece quando no nome EJB-Jar.xml ejb não é igual ao nome da classe EJB.
Por exemplo:

<ejb-name>MySingletonBean</ejb-name>
<ejb-class>ru.rozge.MyTestSingletonBean</ejb-class>

Nesse caso, a GF registra dois feijões com diferentes nomes JNDI ("Java: Global/Mysingletonbean" e "Java: Global/MyTestsingletonBean"). E, na inicialização, cria dois objetos, primeiro - MysingletonBean e Second - MyTestsingletonBean.
Além disso, se você usar a anotação @Resource para recursos de injeção, ações da GF:
1) GF cria o primeiro objeto "mysingletonbean" e os recursos injetados corretamente nele;
2) A GF cria o segundo objeto "myTestsingletonBean" e falha na injeção (todos os recursos injetados equivale a valores nulos ou padrão).
Testado no GF 3.1 Build 12 com @singleton @startup combo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top