0

Netbeans 6.1 x Eclipse Ganymede – Cabe uma reflexão

-

 

Eu trabalho no desenvolvimento Java EE desde 2004 e isso me deixou bem por fora do que acontecia no mundo Java SE. E desde sempre eu utilizei o Eclipse e sempre o preferi ao Netbeans. Porém, esta semana resolvi desenvovler um aplicativo desktop, para agilizar uma tarefa meio monótona que tenho no trampo. A primeira versão foi com Eclipse e o plugin Jigloo, que eu não conhecia e até que achei ok. Ai conversei com um amigo meu (cassolato) e ele me disse que para Java SE, ele utilizavao netbeans, pois o Matisse dava problema com o Eclipse. Bom, resolvi testá-lo, e realmente me surpreendi. Não olhava pra cara do netbeans desde a versão 4.0, e realmente a evolução é notória. Sem falar que ele deu um banho no eclipse no quesito Desktop. Consegui fazer uma nova versão bem mais rápido e com um visual bem melhor.

 

Conclusão: O que é melhor, eclipse ou netbeans ? Bom, prefiro muito mais o eclipse, mas jamais vou tentar fazer um aplicativo desktop outra vez nele, rs…

 

 

0

Plugin de delivery remoto para Maven

-

Vamos, lá, algo bem corriqueiro: Você tem seu projeto Java EE com a build automatizada via Maven2. Ótimo! Ponto para você. Obviamente você quer fazer o deploy deste teu projeto no teu servidor favorito, então você chama:

mvn deploy

Ok ? Bom, infelizmente este comando apenas copia os artefatos do seu projeto (ear, jar, war) para o repositório remoto, ao invés de colocar um ear, por exemplo, no diretorio de deploy do seu JBoss, Tomcat, Weblogic, etc. Frustrante né ? Bom, mas deve haver alguma maneira de eu fazer isso de forma automatizada. Ficar copiando os jars/ears/wars/ na mão é tão, digamos, chato e antiquadro! Bom, para isso existe o plugin Cargo, que até agora não consegui fazer funcionar satisfatoriamente. Ah, também existe um tal de jboss-maven-plugin (que nem merece um link aqui no meu blog =p).

Já que nenhum desses serviu pra mim, resolvi fazer um plugin. E não é que é bem mais simples do que parece ? Em pouco tempo fiz um plugin que copia o EAR do padrão de aplicação que temos aqui na empresa para o servidor remoto, e chama um JMX para fazer o hot-deploy do mesmo. Bacana né ? Bom, o plugin ainda está em estágio inicial, só funciona no JBoss-4.0.4.GA, e não funciona de forma local (JBoss na sua máquina), mas pe bem promissor, uma vez que uma tarefa bem corriqueira e que ninguem da conta.

Estou preparando uma melhor documentação e logo logo disponibilizo aqui no site um tutorial de como usar o plugin, bem como o plugin em si.

Até breve.

0

Como injetar POJOs em um SessionBean via Spring?

-

É fato que a especificação EJB3 trouxe uma enorme facilidade para o desenvolvimento de aplicações Java EE, porém, ainda sinto falta de algumas simplicidades, como por exemplo: “Como injetar um POJO em um SessionBean?” Ok, mas porque eu iria querer fazer isso ? E outra, fiquei sabendo que tem injeção de dependência em EJB3 via annotations, pra que colocar outro container de IoC, como o Spring ?

Ótimas perguntas! Então, vamos lá:

Em primeiro lugar, o IoC do EJB3 só funciona para recursos controlados pelo container, tais como: EJBs, Datasources, Filas, Topicos, etc. Ou seja, se você quiser injetar um POJO, no seu SessionBean, infelizmente não existe uma annotation @POJO, para fazer isso.

Com isso, podemos concluir que para tirar proveito da IoC do seu servidor de aplicação Java EE favorito, você deveria transformar todos os seus objetos de negócio em objetos gerenciados pelo container (traduzindo, EJB), mas isso nem sempre é desejado ou permitido (no caso de você utilizar uma classe ou jar de terceiros, ou compartilhar um modulo com outro projeto que não utiliza EJB). Então, o que fazer ? Simples: AOP!

AOP ?!?! Sim, mas calma, a solução é bem mais simples do que parece. Basta criar uma annotation (@Spring, por exemplo) e implementar o seu próprio interceptor, que irá carrega o seu xml do spring com as definições dos beans (seu applicationContext.xml) e injetá-los, onde estiver marcado com a annotation criada.

A sua annotation poderia ser:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Spring {
        String bean();
}

A mágica:

Aqui vai um exemplo bem simples de interceptor que carrega as configurações do applicationContext, e sai injetado os beans do spring onde tiver uma propriedade anotada com @Spring:

public class SpringInterceptor {

	// AplicationContext - Spring
	private static ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");

	@PostConstruct
	// O Método anotado com PostConstructor deve receber um parametro (InvocationContext),
	// nao deve lançar exceção e o retorno deve ser void
	public void init(InvocationContext invocationContext) {

		// Obtém o session bean que terá as propriedades injetadas
		Object o = invocationContext.getTarget();

		Field[] fields = o.getClass().getDeclaredFields();
		try {
			for (int i = 0; i < fields.length; i++) {

				if (fields[i].isAnnotationPresent(Spring.class)) {
					// Seta o atributo como acessível (sim, quebra o encapsulamento =p )
					fields[i].setAccessible(true);
					// Obtém o nome do Bean e o busca no contexto do spring (ApplicationContext)
					Spring springAnnotation = fields[i].getAnnotation(Spring.class);
					// Injeta o SpringBean(POJO) na propriedade do SessionBean
					fields[i].set(o, appCtx.getBean(springAnnotation.bean()));
				}
			}
		} catch (Exception e) {
                        // Tá, isso pode ser bem melhor ;p
			e.printStackTrace();
		}
	}
}

O Segredo:

Note que toda a lógica do interceptor está no método anotado com @PostConstruct, ou seja o pós-construtor do interceptor. Na verdade este nosso interceptor não intercepta nenhuma chamada. Ele apenas é construído, e na sua construção, injeta os pojos que definimos no arquivo applicationContext.xml. Legal né?

Modo de usar:

Para usar, você tem que indicar, no seu SessionBean, que irá utilizar o interceptor criado:

@Stateless
@Interceptors(value = SpringInterceptor.class)
public class MySessionBean implements MySession {

	@Spring(bean="MyBean")
	private MyBean MyBeanImpl;

        ...
}

Neste caso, a nossa annotation funciona apenas para propriedades (Fields), mas é facilmente expansível para métodos, o que fica como "lição de casa".

0

Vários JBoss na mesma máquina

-

Várias vezes já precisei subir mais de um JBoss na mesma máquina. E para fazer isso eu saia alterando as portas utilizadas pelo servidor em vários arquivos xml. Porém, o JBoss não utiliza somente as portas 8080 e 1099 (que são as mais comuns), o que torna árdua, desgastante e deselegante esta tarefa. Ai juntamos a isso o problema de cada nova versão de jboss disponibilizar as configurações em arquivos diferente e conseguimos algo bem caótico.
Porém, esses dias descobri um truqe bem legal. Você pode subir uma nova instância de JBoss em outro IP dentro da mesma máquina. Basta passar o argumento -b na linha de comando ao iniciar o JBoss (run.bat / run.sh). Ficaria assim:

$JBOSS_HOME/bin/run.sh -c minha_app_1 -b 127.0.0.2
$JBOSS_HOME/bin/run.sh -c minha_app_2 -b 127.0.0.3

Com isso teremos duas instancias de JBoss rodando na mesma máquina e sem conflitos de porta. Mas vale uma ressalva, apenas a sua maquina enxerga esses 2 Jboss, não há como fazer acesso remoto a eles, pois em qual IP você faria lookup ?

0

Dica JMX

-

A Cada dia que passa eu me surpreendo com uma nova “ferramenta” ou utilidade do JMX-Console do JBoss. Desta vez eu estava com um problema na minha aplicação em que as conexões com o banco, de repente, ficavam todas ocupadas, e com isso subia uma exceção falando que a aplicação esperou por 30 segundos, e mesmo assim não conseguiu obter nenhuma conexão do pool. Puts! Foi um parto. Revisei todos os meus DAOs para ver se estava fechando corretamente as conexões. Verifiquei os mapeamentos no spring para ver se algum DAO estava como singleton e por conta disso acabar segurando uma conexão (uma vez que havia um objeto connection dentro do meu DAO abstrato) e mesmo assim nada… Não sabia e não tinha ideia de onde estava ficando pendente a conexão. Eis que surgiu uma luz no fim do túnel. Estava olhando o JBoss console e encontrei 2 MBeans/Serviços que me ajudaram muito o ManagedConnectionPool, e o TransactionManager.
Ambos podem ser iniciado a partir do jmx-console da sua aplicação, basta procurar por esses nomes lá. Com eles, consegui descobrir que ao abrir uma conexão com o banco em um SessionBean (que apenas fazia uma consulta), a mesma ficava atrelada à transação, e ao acessar um WebService dentro desta transação com um tempo de resposta demorado, corria o perigo de esgotar as minhas conexões, dado um acesso concorrente. Depois desta constatação, bastou mudar o tipo de transação do session bean para NOT_SUPPORTED que tudo começou a funcionar.

Portanto, ai vai a dica: ManagedConnectionPool, e TransactionManager, podem te ajudar muito a encontrar possíveis problemas de esgotamento do pool de conexões e deadlocks de transações (respectivamente).