A suite de produtos IBM Tivoli Maximo 7.5 possui diferentes alternativas para a parametrização dos produtos que fazem parte da plataforma. Exemplos dessas alternativas são as aplicações para gerenciamento do banco de dados e da interface do usuário, a definição de workflows, escalações e ainda a criação de scripts em com sintaxe Javascript (Rhino) e Phyton (Jython).
Contudo, mesmo diante das opções dadas pela plataforma, existem casos onde o que desejamos é realmente estender funcionalidades existentes via código Java. Preparar um bom ambiente de desenvolvimento para a criação de extensões é uma tarefa que pode se tornar complicada e, em muitos casos levar a perda de produtividade durante o desenvolvimento.
O objetivo deste tutorial é apresentar algumas opções que poderiam ser utilizadas e fazer uma breve comparação entre pontos positivos e negativos de cada uma. Por fim, mostrar os passos para a criação de um ambiente produtivo para o desenvolvimento de extensões para o Maximo e seus add-ons.
Deployment do IBM Tivoli Maximo
O IBM Tivoli Maximo é uma aplicação que segue o padrão Java EE e
é executada em um servidor de aplicações. O arquivo que é
instalado no servidor de aplicações possui extensão
.ear e é composto por diversos
arquivos .war e
.jar. Vale lembrar que o arquivo
.ear (e os arquivos que o compõem)
são gerados pelo utilitário
buidmaximoear.cmd (ou
.sh para ambientes UNIX). Esse
utilitário basicamente varre o diretório onde o Maximo foi
instalado fazendo o empacotamento dos arquivos.
Um padrão muito comum utilizado na implantação da suite de produtos Maximo é a criação de ambientes intermediários ao ambiente de produção, como desenvolvimento, teste e homologação. Esse padrão é amplamente usado pois permite que exista um ambiente para o desenvolvimento de novas customizações e parametrizações, como por exemplo a criação de novas colunas, alterações em telas existentes, definições de workflows, etc. Uma vez desenvolvidas, as mudanças são promovidas para o segundo ambiente para que sejam executados testes de negócio, normalmente orientados a casos de testes ou mesmo exploratórios. Os testes normalmente são executados por profissionais de Qualidade ou em alguns casos por alguns usuários finais. Aprovadas as mudanças, elas podem ser migradas para os ambientes de homologação e finalmente produção. As migrações entre os ambientes são executadas via Migration Manager [1].
O ambiente onde são desenvolvidas as parametrizações pode ser organizado basicamente de duas formas:
Neste tipo de ambiente existe uma única instância de Maximo instalada em um servidor de aplicações. Todos os desenvolvedores trabalham com essa instância. As principais vantagens deste tipo de configuração são:
- Não é necessária a sincronização das alterações no banco de dados e nem das alterações de tela entre diferentes instâncias;
- Facilidade nas aplicações de eventuais fixpacks, já que só é necessário atualizar um ambiente;
- O ambiente pode ser montado em uma máquina com mais recursos que Desktops e Notebooks.
Contudo, temos também algumas desvantagens:
- Problemas de concorrência nas alterações, principalmente em relação ao banco de dados e às mudanças de tela;
- Caso o ambiente fique indisponível, seja por problemas de infra-estrutura ou por alguma inconsistência na aplicação, toda a equipe fica impedida de continuar desenvolvendo;
- Dificuldades para depuração remota;
- Dificuldades para versionamento dos arquivos customizados;
- Dificuldades para a execução de testes individuais;
Conclusão: Um ambiente compartilhado de desenvolvimento, ainda que possua algumas qualidades, pode não ser uma boa alternativa caso o volume de desenvolvimento seja razoável e existam diversos desenvolvedores no time. Em casos onde existe um único desenvolvedor trabalhando por vez nas customizações a serem feitas no produto, e utilizando as aplicações disponíveis no produto como Database Configuration e Application Designer, um ambiente compartilhado pode ser uma boa alternativa.
Neste tipo de ambiente, cada desenvolvedor possui sua própria instalação de Maximo em um servidor de aplicações individual. A instalação do Maximo até pode ser em uma instância de banco de dados compartilhada com outros usuários, contudo o schema e usuário são exclusivos. As principais vantagens são:
- Redução dos problemas de concorrências nas alterações no banco de dados e interface de aplicações. Cada desenvolvedor pode fazer suas próprias alterações e depois sincronizar com as alterações dos demais desenvolvedores;
- Problemas de infra-estrutura ou inconsistências no um ambiente não impactam necessariamente os demais desenvolvedores da equipe;
- Facilidade para depuração do código desenvolvido;
- Facilidade para versionamento dos arquivos customizados;
- Facilidade para a execução de testes individuais;
Assim como no ambiente compartilhado, também temos algumas desvantagens:
- A aplicação de eventuais fixpacks devem acontecer em todos os ambientes separados e deve ser coordenada. Caso algum desenvolvedor não aplique um fixpack, seu ambiente pode ficar inconsistente com os dos demais, levando a potencial introdução de defeitos;
- Alterações no banco de dados ou na interface com o usuário podem afetar recursos onde mais de um desenvolvedor está trabalhando.
Conclusão: Um ambiente individual de desenvolvimento é uma boa alternativa caso o volume de desenvolvimento seja razoável e existam diversos desenvolvedores no time. Os problemas de sincronização de arquivos é facilmente resolvido com o uso de um repositório de código. Discutiremos como minimizar as desvantagens deste modelo durante o tutorial.
Criando um ambiente individual de desenvolvimento
Pelo fato de o Maximo ser desenvolvido em Java, optamos por utilizar a IDE Eclipse [2] para este tutorial por ser muito popular entre os desenvolvedores Java. O ambiente que vamos montar terá as seguintes características:
- Cada desenvolvedor tem seu próprio servidor de aplicações instalado localmente;
- Cada desenvolvedor tem seu próprio schema de banco de dados. O schema pode estar em um banco de dados local ou em um servidor de banco de dados;
- Cada desenvolvedor tem sua própria instalação de Maximo com eventuais add-ons;
- A instalação do Maximo no servidor de aplicações dos
desenvolvedores não é feita via
maximo.ear, mas sim pelo caminho onde os arquivos .class, .xml e outros recursos estão disponíveis; - O projeto no Eclipse ficará em um diretório diferente do diretório onde o Maximo está instalado e será compartilhado em um repositório de código.
A figura 1 ilustra o ambiente com essas características.
Figura 1. Visão geral
Uma vez que o Maximo tenha sido instalado na máquina onde será executado o desenvolvimento, devemos ter a seguinte estrutura de pastas:
Figura 2. Diretório de instalação do Maximo
A partir deste ponto por questões de simplicidade, passaremos a referenciar o caminho \IBM\SMP\maximo por maximo_root. Estamos assumindo que o Máximo foi instalado com sucesso no banco de dados, e no servidor de aplicações. É fundamental que a instalação do Maximo no servidor de aplicações tenha sido feita como o de uma aplicação que está acessível no disco e não via arquivo maximo.ear . Assumimos que o Eclipse também está instalado, assim como o JDK 1.6.
1 - Criação da User Library
O primeiro passo é a criação de uma nova User Library para agrupar os jars que são utilizados pelo Maximo. Para isso vá em Window > Preferences. Navegue por Java > Build Path > User Libraries e clique em New..., como mostrado na figura 3. Na janela solicitando o nome da biblioteca, preencha com MAXIMO_LIBS.
Figura 3. Nova User Library
O próximo passo é adicionar os arquivos jars do Maximo em nossa biblioteca. Para isso, basta clicar em Add Jars.... Os jars que devemos adicionar estão localizados em dois diretórios:
- maximo_root\applications\maximo\lib: são as bibliotecas utilizadas pelos componentes do Maximo que residem não residem no servlet container, tais como Mbos e MboSets;
- maximo_root\applications\maximouiweb\WEB-INF\lib: são as bibliotecas utilizadas pelas aplicações que residem no servlet container, tais como DataBeans.
Devemos adicionar todos os jars que estão nos dois diretórios em nossa biblioteca. Uma vez que os jars foram adicionados, basta clicarmos em OK no rodapé da janela. Observação: O botão Add Jars fica desabilitado caso algum jar esteja selecionado. Para habilitá-lo, basta selecionar a biblioteca MAXIMO_LIBS.
2- Criação de um novo projeto
O próximo passo é a criação do projeto. Criaremos um projeto Java comum, porém com algumas mudanças em relação ao classpath e as pastas para onde o código deve ser compilado.
Para criar um novo projeto basta clicarmos em File > New … > Java Project. O nome do projeto e o local onde ele deve ser criado é de livre escolha. O mais importante na tela inicial de criação do projeto é manter a opção que separa os arquivos fontes dos que foram compilados (figura 4). Clique em Next para fazer as configurações adicionais.
Figura 4. Novo Projeto
Vamos criar duas pastas do tipo source folder, porém cada uma terá sua própria pasta de saída. A primeira coisa a fazer é marcar o checkbox que possui a descrição Allow output folders for source folders. Esse checkbox serve para habilitar diferentes pastas de saída para o código compilado. Em seguida, devemos criar duas novas source folders.
Clique no link Create new source folder dentro da sessão Details.
Entre como nome de pasta o valor maximo-server-components e clique em Finish. Clique novamente no link, porém agora utilize como o nome da pasta o valor maximo-web-components. O resultado é mostrado na figura 5.
Figura 5. Novas source folders
Podemos reparar que na figura 5, as pastas para onde o resultado da compilação será copiado não estão definidas, o que faz com que o Eclipse as coloque na pasta de saída padrão.
Clique com o botão direito do mouse na primeira pasta a ter seu caminho de saída definido e clique em Configure output folder.... No diálogo apresentado, escolha a segunda opção e clique em Browse.... Crie uma pasta sob o diretório raiz do projeto com o nome de maximo-server-classes. Em seguida selecione a pasta recém criada. Repita o mesmo procedimento para a pasta maximo-web-components, porém nomeando a nova pasta para maximo-web-classes. A figura 6 mostra o resultado dos passos descritos.
Figura 6. Novas source folder
Em seguida, vamos adicionar a biblioteca MAXIMO_LIBS como parte do nosso projeto. Clique na tab Libraries. Nessa tab clique no botão Add Library... e em seguida selecione User Library e clique em Next. Escolha a biblioteca MAXIMO_LIBS e clique em Finish.
Por fim, falta adicionarmos as classes do Maximo no classpath do nosso projeto. Ainda na tab Libraries, clique em Add External Class Folder.... Na janela que foi aberta, navegue até o diretório maximo_root\applications\maximo\businessobjects\classes e clique OK. Repita o processo, porém selecionando agora o diretório maximo_root\applications\maximouiweb\webmodule\WEB-INF\classes. Clique em Finish para que o projeto seja criado. Vale lembrar que essas configurações podem ser alteradas acessando as propriedades do projeto. Podemos ver o resultado na figura 7.
Figura 7. Configuração do classpath
Poderíamos ter optado por criar as pastas de saída como Linked Resources que apontam direto para o diretório onde o Maximo está instalado. Para isso teríamos que definir as pastas de saída (maximo-server-classes e maximo-web-classes) como links para pastas sob a estrutura do Maximo.
Este exemplo segue uma abordagem um pouco diferente que é um pouco mais explícita em relação ao processo de deploy. Criaremos um Builder no nosso projeto que será o responsável por copiar os recursos. O resultado final é igual ao uso de linked resources.
No diretório raiz do projeto, crie um novo arquivo chamado copy-resources.xml com o seguinte conteúdo:
Listagem 1. Arquivo copy-resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="Deploy MyCustomerProject" default="deploy">
<description>Copia os recursos para o Maximo</description>
<!-- definição das propriedades básicas -->
<property name="maximo.app"
location="c:/IBM/SMP/maximo/applications/maximo"/>
<property name="maximo.server.classes"
location="${maximo.app}/businessobjects/classes"/>
<property name="maximo.web.classes"
location="${maximo.app}/maximouiweb/webmodule/WEB-INF/classes"/>
<target name="deploy-server" description="Copia os arquivos - server">
<copy todir="${maximo.server.classes}"
includeemptydirs="false"
overwrite="true"
preservelastmodified="true"
verbose="true">
<fileset dir="maximo-server-classes">
<include name="**" />
</fileset>
</copy>
</target>
<target name="deploy-web" description="Copia os arquivos - web">
<copy todir="${maximo.web.classes}"
includeemptydirs="false"
overwrite="true"
preservelastmodified="true"
verbose="true">
<fileset dir="maximo-web-classes">
<include name="**"/>
</fileset>
</copy>
</target>
<target name="deploy"
description="Copia todos os arquivos"
depends="deploy-server, deploy-web" />
</project>
|
Clique com o botão direito no projeto e em seguida clique em Properties (último item de menu). Selecione então Builders (segundo ítem) e clique em New... e em seguida selecione Ant Builder e clique em OK. Na tela Edit Configuration que foi mostrada, precisamos alterar somente três campos:
- Name: Deve ser informado o nome do Builder. Neste exemplo vamos colocar Deploy classes;
- Build file: Deve ser informado qual o script Ant que será executado. Para selecionar o arquivo copy-resouces.xml, clique em Browse Workspace... e selecione o arquivo;
- Base Directory: Deve ser informado qual o diretório considerado como base para a execução do Builder. Clique em Browse Workspace... e selecione o projeto como diretório base.
Podemos ver o resultado na figura 8. Basta clicar em OK e o novo builder aparece logo após o Java Builder padrão.
Figura 8. Novo Builder
Agora, cada vez que acontecer um build do projeto, os arquivos
das pastas maximo-server-classes e
maximo-web-classes serão copiados
diretamente para o diretório do Maximo.
O arquivo copy-resources.xml pode ainda ser executado
manualmente pela Ant view (Window > Show View... >
Ant).
Podemos reparar que não estamos copiando os arquivos que forem compilados dentro da pasta src para o Maximo. Contudo, caso seja necessário a criação de novas pastas específicas, basta alterar o arquivo copy-resources.xml para que novos diretórios sejam copiados. Devemos notar também que nosso script não remove arquivos que foram copiados, mas os sobreescreve. Caso uma classe deixe de existir, ela deve ser removida manualmente da estrutura de diretórios do Maximo.
Os arquivos que estão sendo copiados durante o processo de build do projeto são listados no console de saída do Eclipse.
2- Criação do script para criação dos stubs RMI
A invocação dos métodos que são parte de componentes como Mbos
pelos componentes que ficam no servlet container é feita via
interfaces remotas e seus stubs. Caso sejam criados novos Mbos
ou novas extensões, é necessário a geração dos stubs. Para isso,
criaremos um outro arquivo de script.
No diretório raiz do projeto, crie um novo arquivo chamado
build-rmi-stubs.xml com o seguinte
conteúdo:
Listagem 2. Arquivo build-rmi-stubs.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyCustomerProject" default="build">
<description>Compila Stubs das interfaces remotas</description>
<!-- definição das propriedades básicas -->
<target name="init" description="Inicializacao">
<property name="maximo.app"
location="c:/IBM/SMP/maximo/applications/maximo"/>
<property name="maximo.server.classes"
location="${maximo.app}/businessobjects/classes"/>
<property name="local.classes"
location="${basedir}/maximo-server-classes"/>
<property name="stubversion" value ="1.2"/>
<property name="build.rmic" value="sun"/>
</target>
<target name="build" depends="init" description="Geracao dos stubs">
<rmic base="${local.classes}"
classpath="${maximo.server.classes}"
stubversion="${stubversion}">
<!-- <include name="meu/pacote/MinhaClasse.class"/> -->
</rmic>
</target>
</project>
|
O script deve ser executado apenas quando houver a criação de uma
nova classe que possua uma interface remota, ou se a interface
remota de alguma classe já existente for alterada. As classes
que possuem as interfaces remotas devem ser incluídas entro da
tag rmic, como exemplificado. Assim
como o arquivo copy-resources.xml, este arquivo também
pode ser executado na Ant view.
Importante: Caso o JRE esteja sendo utilizado ao invés do JDK, o processo de compilação dos stubs falha. Tenha certeza que o Java utilizado no projeto aponte para uma pasta com JDK.
3- Depuração
Em muitos casos é necessário para o desenvolvedor depurar o
código que está sendo desenvolvido (o famoso "debug"). O
ambiente que é apresentado neste artigo foi montado de modo a
permitir que o código customizado seja facilmente depurado.
A abordagem que utilizaremos para depuração é a de nos
conectarmos remotamente ao código. O servidor de aplicações deve
ser iniciado em modo de debug. Cada servidor de aplicações
possui uma maneira de iniciar desta maneira. Por exemplo, no
Websphere Application Server o servidor é configurado para modo
debug via console administrativo. Já no Oracle Weblogic, o
script que inicializa o servidor possui algumas linhas
adicionais com argumentos para a JVM.
Em ambos os casos, o mais importante é saber qual a porta onde o debugger deverá se conectar. Essa informação é necessária para configurarmos uma Java Remote Application no Eclipse.
Para criamos a configuração de debug de uma aplicação remota,
devemos clicar com o botão direito no projeto e em seguida em
Debug As.. > Debug Configurations.
Na tela de Debug Configurations devemos criar
uma nova Remote Java Application como mostrado
na figura 9. Na tab Connection devemos entrar a
informação de conexão para o servidor de aplicações como o
endereço (que como estamos executando localmente será localhost)
e a porta. Na tab Source devemos adicionar
nosso projeto para que o Eclipse consiga encontrar os fontes
durante o processo de depuração (figura 10).
Figura 9. Configuração de Debugger
Com as configurações feitas, uma vez que o servidor de aplicações esteja com o Maximo em execução, basta executarmos a configuração de debug criada para que o Eclipse se conecte com o servidor de aplicações. Break points que estejam presentes no código customizado forçaram uma interrupção na execução. Podemos então fazer a depuração do código customizado.
Figura 10. MyCustomProject como Source do debugger
4- Limitações
Mesmo com o ambiente apresentado, ainda há alguns processos não automatizados. Enumeramos a seguir os principais, explicando em alguns casos como minimizá-los:
- Sincronização de bancos de dados e UI entre os desenvolvedores: O problema de sincronização das alterações de bancos de dados pode ser resolvido de diversas maneiras, indo desde o uso das aplicações relacionadas ao Migration Manager para a geração de pacotes nos casos mais complexos e com mais alterações, ou até mesmo cada desenvolvedor aplicar manualmente as alterações em seu banco de dados nos casos mais simples. Sobre as mudanças relacionadas a interface gráfica, as alterações podem ser exportadas em formato XML e adicionadas no repositório de código;
- Troca "a quente" de código durante depuração: Como estamos trabalhando com a cópia dos arquivos acontecendo de modo automático do nosso diretório de desenvolvimento para o Maximo, durante a depuração do código, eventuais alterações poderão não ter efeito até que o servidor de aplicações seja reiniciado. Vale destacar que mudanças no código dentro de métodos existentes não necessitam da reinicialização do servidor;
- Remoção automática de arquivos: Novamente pelo fato de estarmos trabalhando com a cópia dos arquivos acontecendo de modo automático, eventuais arquivos que sejam removidos no diretório de trabalho não são automaticamente removidos do diretório do Maximo. É necessário que esses arquivos sejam removidos manualmente.
5- Considerações finais
É recomendado, sempre que possível, não fazer customizações no produto via código mas sim via ferramentas providas pela plataforma, como os listados no início do artigo. Ainda assim, customizações podem ser necessárias.
A abordagem de desenvolvimento apresentada neste artigo, mesmo com algumas limitações, ainda assim permite que o time de desenvolvimento seja produtivo e organizado. Não foi parte do escopo do artigo, mas testes unitários poderiam ser facilmente adicionados a estrutura, assim como ferramentas para builds automatizados.
[1] Migration Use Cases with Migration Manager - http://www.redbooks.ibm.com/abstracts/sg247906.html?Open
[2] Eclipse - http://www.eclipse.org/
Baixe um exemplo de projeto criado com os passos do artigo

Engenheiro de Software e líder de desenvolvimento no laboratório de Software da IBM Brasil com 5 anos de experiência no desenvolvimento de Maximo. Possui bacharelado em Ciência da Computação e é aluno de mestrado na área de Sistemas Distribuídos no IME-USP. Perfil My Developer Works: https://www.ibm.com/developerworks/mydeveloperworks/profiles/html/profileView.do?key=8ed681cc-051d-4157-a90d-d1eb9061d0bd