My recent posts

AppEngine, Guice e GuiceBerry

Já faz um bom tempo desde meu último post, estive dedicando ao novo trabalho (http://zup.com.br/) e a concluir minha graduação. Nestes últimos tempos andei pesquisando e estudando bastante sobre esse novo mundo para desenvolvedores de softwares especialistas em Java, o mundo Google.

        Mesmo eu tendo recentemente descoberto tudo isso, aparentemente todo esse mundo existe a muito tempo. Digo isso pois todas as ferramentas que conheço (mesmo não sendo muitas hehe) de desenvolvimento de software Java, possuem integração ou alguma alternativa neste mundo novo. Desde melhorias e novas implementações no topo do framework de collections (Google Collections - http://code.google.com/p/google-collections/, hoje faz parte de um projeto maior (Guava - http://code.google.com/p/guava-libraries/) que possui excelentes implementações e melhorias não somente para collections, mas também para cache, concorrência, E/S e etc) até o que é pra mim atualmente a melhor plataforma de cloud computing existente no mercado, o Google AppEngine.

Tanto pelos serviços que oferece que são de excelentíssima qualidade, confiáveis, escaláveis e etc. Mas também pela forma que oferece, o desenvolvedor ou empresa pode implantar seus protótipos e os desenvolvê-los sem nenhum custo, testar para ver se o resultado atingido é o desejável e dependendo da intenção e tamanho da aplicação até funcionar sem nenhum custo. Isso mesmo, uma aplicação Java na nuvem, com todas as capacidades possíveis: banco de dados distribuído, banco de dados de arquivo, serviço de messageria, tarefas agendas e muito mais sem nem sequer um real de custo.

Ao entrar neste mundo fui quase que automaticamente levado a conhecer outros dois importantes atores neste novo mundo.

Google Guice(http://code.google.com/p/google-guice/), um framework de injeção de dependência, mas não apenas mais um como alguns poderiam pensar, este hoje é uma revolução na forma de se trabalhar com injeção de dependência. Uma revolução que se torna um padrão, literalmente, através da implementação do Guice, que hoje faz um enorme sucesso no mundo todo, surgiu então uma nova Java Specification Release, a JSR-330 é a especificação que padroniza e especifica como deverá ser implementado injeção de dependência no Java. Existe uma promessa que essa funcionalidade faça parte do Java SE 8 nativamente, legal né?

        Um outro fato curioso é que o tão aclamado CDI e a JSR-330 aparentemente estão convergindo para o mesmo, sendo CDI apenas um módulo (conceito da JSR-330 / Google Guice) que provê alguns objetos “especiais“. O próximo post farei até fim da próxima semana e será especificamente sobre Google Guice. Já possuo projetos utilizando ele no meu GitHub e trarei uma nova implementação para ser usada como referência para novos projetos!

O segundo e também bastante importante chama-se GuiceBerry, que é basicamente uma forma de se integrar de forma rápida, fácil e flexível seu código com suas classes JUnit. Se você se pergunta o porque isso seria interessante, onde isso iria te beneficiar eu já lhe respondo agora. Você já deve ter se encontrado em uma situação onde uma classe não podia ser testada efetivamente pois ela possuia dependência de algo que tornava os testes muito difíceis ou até impossíveis, com Google Guice e GuiceBerry você poderá criar seus módulos e assim injetar implementações distintas para as interface desejadas em momentos diferentes.

        No código que você implantará em produção você instala um módulo contendo a implementação real enquanto no módulo que utilizará para testar ou para apoiar seus testes você instalará o módulo contendo falsas implementações para reproduzir o mesmo comportamento da implementação original. Também é possível atingir isto utilizando mocking, mas eu particularmente gosto de ter controle do código que minha implementação está gerando. Sem contar no nível de flexibilidade e legibilidade do código. Falarei mais sobre como instalar módulos, configurar o GuiceBerry e muito mais no tutorial de Google Guice e GuiceBerry da próxima semana.

Em seguida começarei uma sequência de tutoriais práticos das funcionalidades do Google AppEngine e tentarei passar tudo que consegui assimilar como sendo boa prática enquanto desenvolvendo no topo dessa plataforma. Obrigado e até a próxima! :)


#CPBR4 @ Interfaces tangíveis!

Hoje 18 de janeiro de 2011 ministrei uma palestra sobre interfaces tangíveis através da visão computacional, e como prometido segue o material gerado e estudado acerca do assunto: http://www.megaupload.com/?d=78KVD5FR, para me contactar através de e-mail/msn/gtalk utilize jayrmotta@gmail.com


Configurando JMS + Spring + JBoss

 

Recentemente precisei configurar um provedor/consumidor de mensagens no projeto em que estou trabalhando, o mesmo utiliza Spring, durante minha pesquisa sobre como configurar JMS no Spring me coloquei em diversos cenários confusos, o que me motivou a escrever tanto minha perspectiva sobre o que eu li e sobre como eu solucionei o meu problema para que caso alguém tenha o mesmo problema possa solucioná-lo de forma rápida e com embasamento técnico.

Eu precisava interceptar todas as requisições http e registrar dados referentes a navegação dos usuários do sistema que estou desenvolvendo, porém devido ao grande número de requisições e em horários específicos eu poderia sobrecarregar minha base de dados ao tentar persisti-los, a solução seria algo que funcionasse como uma espécie de buffer de requisições, algo que pudesse armazenar de forma linear. Java Message Service era o que eu precisava.

Uma pessoa me indicou utilizar o Apache ActiveMQ, uma solução JMS que não depende de container. Ao pesquisar sobre ele descobri que inúmeros projetos o utilizam e que é relativamente simples de se configurar, porém devido a alguns testes de performance e algumas premissas do meu projeto não pude utilizá-lo, espero poder testa-lo ainda um dia.

Após concluir que não utilizaria o ActiveMQ o que me restava era o JBossMQ uma implementação JMS provida pelo JBoss o que é excelente dado o meu contexto pois o mesmo não tornava meu projeto dependente de uma implementação de JMS específica, e com a vantagem de poder configurar e controlar minhas Filas/Tópicos (Queues/Topics) no console web do JBoss, e em tempo de execução. Muita pesquisa, muitos testes .. leitura pra cá, leitura pra lá .. é hora de implementar hehe, tempo é dinheiro né?! :P

No applicationContext.xml do meu spring coloquei os seguintes trechos XML para configurar o JMS e uma fila:

Lookup JNDI para a fábrica de conexões do seu servidor de aplicação:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:jee="http://www.springframework.org/schema/jee"       
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd" default-autowire="byName">

<jee:jndi-lookup jndi-name="QueueConnectionFactory" id="jmsConnectionFactory" expected-type="javax.jms.ConnectionFactory">
</jee:jndi-lookup>

Container de listeners JMS, é possível configurar vários containers com várias configurações distintas, cada um contendo diversas Filas/Tópicos. “Mas mestre Yoda, porquê eu iria querer escrever tudo isto enquanto eu poderia resumir tudo em um único container?”, o mestre responde: “Você ouvia Justin Bieber quando eu dei a lição sobre containers JMS, não é mesmo?”. O container é quem diz quantas instancias de cada listener vão poder ser instanciadas, é nele que você poderá dizer quem irá resolver o nome de sua fila caso tenha específicado uma fila dinâmica (essa fica pra outra aula, muhahahaha) e etc. O container é muito poderoso! Eis o que eu configurei, básico e atende as minhas necessidades:

<jms:listener-container concurrency="1" connection-factory="jmsConnectionFactory">
<jms:listener destination="HttpRequestQueue" ref="httpRequestQueueListener" />
</jms:listener-container>

Notem que o container possui uma referência ao nosso listener que eu mostrarei logo abaixo. Também é preciso criar um JMSTemplate, que é uma implementação específica do Spring para abstração de mensagens JMS, notem que ele utiliza uma referência da fábrica de conexões criada anteriormente:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>

Para concluir precisei criar um bean para representar minha fila em um objeto e também o listener (citado a cima) e o produtor de mensagens (que utiliza o JMSTemplate + o objeto da Fila):
A fila:

<jee:jndi-lookup jndi-name="queue/HttpRequestQueue" id="httpRequestQueue" expected-type="javax.jms.Queue">
</jee:jndi-lookup>

O listener:

<bean id="httpRequestQueueListener" class="br.com.latu.frontend.jms.HttpRequestQueueListener"/>

O produtor:

<bean id="httpRequestQueueSender" class="br.com.latu.frontend.jms.HttpRequestQueueSender">
<property name="jmsTemplate">
<ref bean="jmsTemplate"/>
</property>
<property name="destination">
<ref bean="httpRequestQueue"/>
</property>
</bean>

A classe do listener:

package br.com.latu.frontend.jms;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.apache.log4j.Logger;
import org.springframework.jms.listener.SessionAwareMessageListener;

public class HttpRequestQueueListener implements MessageListener, SessionAwareMessageListener {

	private static final Logger log = Logger.getLogger(HttpRequestQueueListener.class);

	public void onMessage(Message message) {

		try {

			this.onMessage(message, null);

		} catch(JMSException j) {

			HttpRequestQueueListener.getLog().debug(message, j);

		}

	}

	public void onMessage(Message message, Session session) throws JMSException {

		if (message instanceof ObjectMessage) {

			// No meu caso irei pegar um objeto deste lado e irei persistir.

		}

	}

	public static Logger getLog() {
		return log;
	}

}


A classe do produtor:
package br.com.latu.frontend.jms;

import javax.jms.Destination;

import org.apache.log4j.Logger;
import org.springframework.jms.core.JmsTemplate;

public class HttpRequestQueueSender {

	private static final Logger log = Logger.getLogger(HttpRequestQueueSender.class);

	private JmsTemplate jmsTemplate;
	private Destination destination;

	public void sendObjectMessage(Object object) {
		try {

			if(object == null) throw new IllegalArgumentException();
			this.getJmsTemplate().convertAndSend(this.getDestination(), object);

		} catch(IllegalArgumentException e) {

			HttpRequestQueueSender.getLog().debug("The argument object can't be null.", e);

		}
	}

	public JmsTemplate getJmsTemplate() {
		return jmsTemplate;
	}

	public Destination getDestination() {
		return destination;
	}

	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}

	public void setDestination(Destination destination) {
		this.destination = destination;
	}

	public static Logger getLog() {
		return log;
	}

}

Notem que existe no código HttpRequestQueue e queue/HttpRequestQueue em alguns lugares, esta eu configurei no xml jbossmq-destinations-service.xml, com isso você já será capaz de interceptar mensagens enviadas para esta fila e enviar também. Caso tenham dúvidas e sugestões enviem comentários, responderei o mais rápido possível. Obrigado! :P

http://static.springsource.org/spring/docs/2.5.x/reference/jms.html


EMSL’10 @ Interfaces tangíveis!

INTERFACES TANGÍVEIS ATRAVÉS DA VISÃO COMPUTACIONAL!

Interfaces quem?“, pode ser o que vem a cabeça de muitos ao ouvir este título, porém junto com a computação visual uma nova gama de possibilidades é criada, permitindo que novas interfaces para o que nos é trivial e até novas aplicações sejam desenvolvidas.

Hoje quinta-feira 14/10/2010, eu ministrei uma palestra falando sobre este assunto no evento EMSL’10, pessoas das mais diversas áreas de atuação compareceram e pudemos falar um pouco sobre conceitos voltados ao assunto e como construir aplicações para tais interfaces.

Segue o link contendo o material utilizado e gerado durante a palestra para os que se interessarem: http://www.megaupload.com/?d=EER1AHO6 ( Senha: interfacestangiveis )

Gostaria de agradecer aos que participaram e peço que mantenham contato, obrigado!

http://emsl.softwarelivre.org/ @ EMSL’10


WebServices, i’m in baby! ;D 2

Haaai ;D … No primeiro tópico eu postei como criar um WebService bem simples com JAX-WS e hoje mostrarei como criar um client para o WS (acrônimo para WebService ;P) anteriormente criado.

There we go!


package com.jmotta.webservices.test;

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.jmotta.webservices.interfaces.TimeService;

public class TimeServiceClient {

	public static void main(String[] args) throws Exception {

		URL url = new URL("http://127.0.0.1:9876/ts?wsdl");

		QName qname = new QName("http://classes.webservices.jmotta.com/", "TimeServerImplService");

		Service service = Service.create(url, qname);

		TimeService eif = service.getPort(TimeService.class);

		System.out.println(eif.getTimeAsLong());
		System.out.println(eif.getTimeAsString());

	}

}

Como podemos observar é criado uma instância da classe URL que armazena uma String contendo o endereço para o WSDL do serviço que escrevemos, logo após criamos um QName que é o nome qualificado do serviço passando um URI (encontrado no seu WSDL na tag definitions, atributo targetNamespace ) como primeiro argumento e o segundo é o nome do serviço publicado no WSDL. Em seguida é criado uma instância de Service passando como argumento a instância de URL e QName anteriormente criadas, após isso uma instância da interface EndPoint recebe um objeto do método getPort de Service (getPort tem esse nome pois cada serviço em um WS é descrito nos port types), tal objeto implementa os métodos descritos na interface contendo a lógica necessária para chamar o WS e devolver o resultado esperado passando a sensação de estar realmente acessando os métodos diretamente, enquanto na verdade ele encapsula a lógica de consumo do WS. Voltando onde nos interessa, para finalizar fiz uma chamada a cada método que a interface descreve como argumento para a saída padrão do sistema operacional.

Simples! Funcional e serve como ponto de partida para o mundo dos WebServices em Java! ;D

Até a próxima! Cya


WebServices, i’m in baby! ;D

Pi-rei! Hahuahauhauah ..

Aquela sensação de quando faz o primeiro código e tudo funciona .. até que criar WebService com java é bem simples, li as 10 primeiras páginas do livro “Java Web Services: Implementando, de Martin Kalin. Copyright 2009 Martin Kalin” e com 30 minutos de testes e leitura escrevi o meu primeiro WebService, bem simples porém um WebService.

Três arquivos java escritos. That’s it.

package com.jmotta.webservices.interfaces;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style = Style.RPC)
public interface TimeService {

	@WebMethod String getTimeAsString();

	@WebMethod long getTimeAsLong();

}

package com.jmotta.webservices.classes;

import java.util.Date;

import javax.jws.WebService;

import com.jmotta.webservices.interfaces.TimeService;

@WebService(endpointInterface = "com.jmotta.webservices.interfaces.TimeService")
public class TimeServerImpl implements TimeService {

	@Override
	public String getTimeAsString() {
		return new Date().toString();
	}

	@Override
	public long getTimeAsLong() {
		return new Date().getTime();
	}

}

package com.jmotta.webservices.test;

import javax.xml.ws.Endpoint;

import com.jmotta.webservices.classes.TimeServerImpl;

public class TimeServerPublisher {

	public static void main(String[] args) {

		Endpoint.publish("http://127.0.0.1:9876/ts", new TimeServerImpl());

	}

}

Depois é só abrir um browser, acessar a URL descrita no parâmetro da classe EndPoint com o final “?wsdl” e mandar exibir o código fonte.
Detalhe é que isso é somente o WebService heh, minha maior virtude não é paciência hehe .. vou voltar a codar o cliente pra esse WebService ;D

Cya ;D


Follow

Get every new post delivered to your Inbox.