INTRODUÇÃO
Nesse
artigo explicaremos a construção de bundles OSGi que criam e usam
serviços. Para isso, vamos usar o IDE Eclipse 3.7 (Indigo) e a
implementação OSGi Eclipse Equinox.
A
tecnologia OSGi preenche o buraco da falta de modularidade nos jars
da linguagem Java e também, prove algumas características:
- Instalação, inicio, finalização, desinstalação de modo dinâmico, sem necessitar parar a aplicação Java. Isso é uma característica muito usada em servidores de aplicação como JBoss AS, Glassfish, Weblogic e outros. Mas, uma aplicação Java qualquer pode usar esse mecanismo, provido pelo framework OSGi. Assim, podemos desenvolver uma aplicação desktop que pode de maneira dinâmica (sem reinício, parada), instalar e desinstalar componentes (por exemplo).
- Isolamento dos componentes (bundles), pois cada bundle possui o seu Classloader e se algum bundle “morrer”, os outros bundles permanecem ativos.
- Controle de visibilidade de pacotes, pois com os uso dos jars, todas as classes públicas ficam visíveis no classpath da aplicação, mas num bundle OSGi, podemos restringir a visibilidade das classes, de maneira que exportamos apenas as classes que poderão ser usadas por outros bundles.
- Criação e uso de serviços sobre a VM, podemos ter um bundle que cria o serviço, com um determinado nome e do outro lado, teremos n bundles chamando e executando o serviço definido no bundle original. Podemos monitorar as alterações nos serviços no contexto da aplicação, através do uso de ouvintes (listeners) que são chamados quando algum serviço é alterado.
- Versionamento, podemos ter bundles com os mesmos nomes mas em versões diferentes, algo que com o uso de jars simples, não podemos ter a mesma classe definida em dois jars diferentes e no mesmo classpath, pois no momento da busca da classe pelo Classloader, a primeira classe encontrada é que será usada. No OSGi, temos o controle de versão, então, podemos definir quais pacotes de tais versões queremos importar.
CONSTRUÇÃO DO
EXEMPLO DE UM TRADUTOR
Vamos criar um sistema
que traduz palavras para um idioma de destino, a ideia é ter um
bundle que define a interface, vamos chamar de “TradutorCore”, e
para cada idioma de destino, vamos criar os bundles “TradutorEnglish”
para implementar a interface para traduzir palavras para o idioma
inglês e “TradutorSpanish” para implementar a interface para
traduzir palavras para o idioma espanhol. E um bundle para cliente
para consumir os serviços criados, vamos chamar de
“TradutorCliente”.
BUNDLE
“TradutorCore”
Nas figuras a seguir,
será mostrado passo a passo o processo de criação de bundle OSGi
no IDE Eclipse (Versão indigo 3.7.2).
BUNDLE
“TradutorEnglish”
Nas
figuras a seguir, será mostrado o processo para criar o bundle que
implementará o serviço de tradução (interface ITradutor). Como o
processo de criação de bundle já foi explicado detalhadamente no
bundle “TradutorCore” e também, da mesma maneira que criamos o
bundle anterior, podemos criar esse, então nas figuras a seguir
serão mostradas apenas os passos distintos e com algumas
observações.
.getServiceReferences(ITradutor.class.getName(),
"("
+
ITradutor.LANGUAGE + "=*)");
if
(tradutores != null) {
for
(int i = 0; i < tradutores.length; i++) {
if
(tradutores[i] != null) {
ITradutor
t = context.getService(tradutores[i]);
if
(t != null) {
List
words = t.translate("Qualquer coisa "
+
Calendar.getInstance().getTime());
System.out.println("Traduções:
" + words);
}
}
}
}
System.out
.println("Bundle
TradutorCliente - Tradutores: " + tradutores);
}
private
static class ServiceClientListener implements ServiceListener {
private
Activator ac;
public
ServiceClientListener(Activator ac) {
this.ac
= ac;
}
@Override
public
void serviceChanged(ServiceEvent arg0) {
if
(ServiceEvent.MODIFIED == arg0.getType()) {
System.out.println("Serviço
modificado: " + arg0.getSource());
} else
if (ServiceEvent.REGISTERED == arg0.getType()) {
System.out.println("Serviço
registrado: " + arg0.getSource());
} else
if (ServiceEvent.UNREGISTERING == arg0.getType()) {
System.out
.println("Serviço
desregistrado: " + arg0.getSource());
} else
if (ServiceEvent.MODIFIED_ENDMATCH == arg0.getType()) {
System.out.println("Serviço
modificado endmatch: "
+
arg0.getSource());
} else
{
System.out.println("Serviço
outros eventos: "
+
arg0.getSource());
}
try {
ac.execute();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
RODANDO OS BUNDLES
NO IDE ECLIPSE
O próximo
passo é executar os bundles criados e mostrar os serviços sendo
registrados, chamados e desregistrados. Para isso, precisamos
executar os bundles em cima de alguma implementação do framework
OSGi como Eclipse Equinox, JBoss AS 7.x, Apache Felix e outros. E por
sua vez, esses frameworks rodam em cima de JVM. Nesse artigo
mostraremos apenas a execução desses bundles dentro da
infraestrutura de desenvolvimento providenciada pela IDE Eclipse,
conforme mostra as figuras a seguir.
CONCLUSÃO
Nesse
artigo mostramos a construção e execução de bundles OSGi sobre o
framework OSGi Eclipse Equinox. Nesses bundles, desenhamos uma
estrutura simples de uso e consumo de serviços através do uso do
mecanismo de serviços da API da especificação OSGi.
Com isso,
promovemos o isolamento da implementação da interface com o uso do
objeto que implementa a interface, pois o cliente que invoca métodos
(serviços) da interface não necessita conhecer a classe que
implementa essa interface. Pois com o uso do OSGi, teríamos um
bundle para definir as interfaces, outros para implementá-las como
serviços e outros bundles para chamar essas implementações, mas
sem conhecer a classe que implementa essas interfaces, promovendo
maior desacoplamento no código. E também, não ficamos presos a uma
implementação particular do framework OSGi, pois qualquer framework
OSGi pode ser usado para executar os bundles descritos nesse artigo.
REFERÊNCIAS
Nenhum comentário:
Postar um comentário