quinta-feira, novembro 20, 2008

Google Themes

Adorei.

Convenhamos, embora o visual do Gmail não seja enfadonho, ele carecia muito de uma forma de modificar sua aparência.

Eu lembro de uma vez ter instalado um plugin para permitir algo parecido. Entretanto, essa nova feature nativa do branquelo é muito legal.

Abaixo, uma figura do Gmail num estilo retrô: "carregado" sim, mas muito show!




PS. Quem usa o Apache Maven vai notar uma singela semelhança no logo :)

terça-feira, novembro 11, 2008

Gerencia de Riscos e Incidentes de Projeto pelo Jira

O Jira e a Sua Arquitetura Escalável
É fato que o Atlassian Jira não é uma ferramenta para gerência de projetos. Ele é uma ferramenta para a gerência de issues (e deixo para o leitor a tradução literal desse termo - embora eu considere uma issue uma coisa qualquer que precisa ser controlada e, obviamente, resolvida em algum momento).

Não obstante a isto, eu utilizao o Jira como ferramenta para a gerência de projetos, e o considero superior em muitos aspectos mesmo em relação à ferramentas criadas especificamente para isso, tais como o TraceGP, o DotProject, o MSProject ou mesmo o (caro) Primavera.

Considero o Jira algo como a IDE Eclipse, que ao primeiro contato consideramos insuficiente e rudimentar, mas que para o bom utilizador, facilmente transforma-se naquilo que quisermos e com uma eficiência e eficácia incomparáveis frente a outros produtos.

Isso ocorre porque o Jira - assim com todos os outros produtos da australiana Atlassian - é uma ferramenta com uma arquitetura aberta, escalável e propenso a plugins de quaisquer natureza.

Como características que mais eu gosto no Jira estão seus Workflows e telas (Screens) customizáveis. E são justamente estas características as que exponencializam o seu poder.

Entretanto, este post não fala desses recursos, e sim do uso de campos customizados.

Riscos e Incidentes Através de Tarefas e Campos Customizados
Nos nossos projetos, diversos campos customizados são utilizados em conjuto com tipos de tarefas distintas, criadas especificamente para o nosso modelo de negócio.

Assim, para este post, duas tarefas são de suma importância: tarefas que representam riscos de projeto e tarefas que representam incidentes de projeto.

Risco de projeto é tudo aquilo que, caso ocorra, pode impactuar no aumento do custo (monetário, temporal, de recursos, etc) do projeto.

Incidente de projeto é tudo aquilo que (tenha sido ou não mapeado anteriormente) evento ocorrido ue interfere danosamente no projeto.

Conseguir gerenciar (e contornar) os riscos e evitar os incidentes é uma das tarefas do gerente do projeto.

Outra atividade de gerência importante - porém muitas vezes negligenciada - é co-relacionar os riscos e incidentes, verificando sua causa, responsabilidade, atividades de contorno, impacto e outras ações.

Tudo isso eu faço no Jira, usando:

1. Um tipo de tarefa para registrar riscos: que são convertidos em "horas-de-projeto" para mensurar seu impacto no projeto.

2. Um tipo de tarefa para registrar incidentes: que efetivamente marcam quantas "horas-de-projeto" quando ocorrem.

3. Um campo customizado de issue que indica a responsabilidade do incidente, que eu gosto de vincular a um desses valores: O Cliente (quando o cliente foi responsável pelo incidente); A empresa (quando nós fomos os responsáveis pelo incidente); Terceiro (quando um terceiro - como um outro fornecedor do cliente - foi o responsável pelo incidente). NOTA: Caso seja necessário identificar o nome da pessoa (ou outro recurso) causador do problema, eu opto por usar o campo "Comentários" da tarefa, onde eu posso usar o (ótimo) sistema de segurança do Jira para escolher para quais perfis do projeto (por exemplo, diretores, gerentes, etc) vão saber essa informação.

4. Relacionamentos do tipo (pode ser qualquer tipo, mas eu uso estes) "is derivated from" e "derive to".

5. Uma matriz de relacionamento entre tarefas do projeto que são do tipo "Risco de Projeto" e "Incidente de Projeto", a qual mostra os pontos onde os riscos transformaram-se em incidentes.

Aqui, tento mostrar isso:

Informações Úteis
Juntando tudo isso, eu posso facilmente localizar todos os riscos do projeto e mostrar para diretoria, indicando "olha, se isso ocorrer, o impacto no projeto vai ser tantas hora a mais ou então tando $ a mais" ou mesmo "olha, esses riscos existem, e podem ser contornados, cada um, dessa forma" ou ainda "olha, esses riscos existem, e a maioria deles é de origem interna nossa, onde nossos desenvolvedores precisam um treinamento maior na tecnologia X".

Outra coisa que dá para mostrar, é a relação entre Riscos e Incidentes, como "olha, mesmo nós tendo mostrado lá no início do projeto que existiam X riscos no projeto, os Y incidentes ocorreram derivados desses riscos, sendo que a maioria foi em consequência da falta de segurança no componente Z do projeto, que era gerenciado pela pessoa P, a qual (hoje sabemos) não nunca tinha trabalhado com isso antes".

Resumindo
Queria escrever muito mais sobre técnicas que usamos sobre o Jira para mantermos nossos projetos e que, como disse, ao usuário de primeira viagem, passam despercebidas nessa maravilhosa ferramenta.

Como disse, outras ferramentas como as comentadas acima têm módulos para conseguir essas informações, mas a flexibilidade (nem entrei no mérito de criar fluxos - Workflows - customizados para gerenciar cada um desses Riscos ou Incidentes) que o Jira possui.

Em suma, o Jira é muito show :)

sexta-feira, setembro 05, 2008

Putz, mais um : Super CRUD

Hoje meu amigo R. mandou um email para mim (seira eu?) e, conforme ele indicou, dei gargalhadas com isso. Estou falando do SuperCRUD.
Desculpe Vinicius, sua iniciativa é boa (como tantas outras), mas sinceramente, essa técnica de geração de telas de cadastro está mais do que batida. Na verdade, é do tempo do meu pai. Qualquer gerador que produza código-fonte somente produz uma coisa: legado.
Sempre fui contra geradores de código, e não é estigma, é "dor no osso "de tanto ver soluções assim prometerem milagres e não darem em nada.
Olhei os demos do site, e bem, outra piada: não vi o resultado da geração, ou seja, não vi as telas geradas!
Contras? Todos. Gera código-fonte, é baseado em templates, não existe uma arquitetura de reuso (apenas templates extensíveis e vagamente compartilháveis), etc, etc, etc.
De todos os frameworks e propostas que vi (e acreditem meninos, já vi dezenas), o Metawidget ainda é o mais elegante e, claro, não gera código-fonte ;)
Sorry aos que discordam.

segunda-feira, setembro 01, 2008

Como Estimar Projetos Grandes

Introdução 1 – os apressados podem pular se quiserem

Estimar não é uma arte. É matemática.

Quando erramos “para mais” (ou seja, quando o projeto extrapola o cronograma, os custos ou o esforço mensurados) ficamos cheios de respostas para tudo e ainda mentimos para nós mesmos que simplesmente a culpa não foi nossa: foi o contexto que mudou (como se essa mutabilidade não fosse uma variável que precisasse estar na nossa equação...).

Quando erramos “para menos” (ou seja, quando o projeto é concluído com êxito antes do prazo ou com menor custo ou esforço) ficamos boquiabertos com nosso poder de gerência, gestão e capacidade de inferência. Em suma, ficamos aguardando os louros da “vitória” e a enxurrada de parabéns dos colegas, com a certeza de que fizemos tudo melhor do que o esperado. Triste ilusão.

Errar para menos é errar, ora pois! Quando erramos para menos, sub-utilizamos recursos e tempo, e consequentemente, estamos perdendo algo. Mas que algo é esse? Podem ser recursos humanos que não foram utilizados em outras tarefas ou projetos; podem ser recursos físicos, que não puderam ser usados ou realocados; podem ser recursos abstratos, como a compra demasiada de licenças de software, enfim, pode ser uma panacéia de coisas este desperdício.

Assim, para termos a precisão adequada, não podemos nos valer apenas de achismos. Estimar não é uma arte, é matemática.

Introdução 2 – Os apressados podem pular novamente se quiserem

Sistemas complexos são dirigidos por inúmeras variáveis.

Na meteorologia, por exemplo, considerar o atrito causado pela passagem ocasional de bandos de Andorinhas pelo ar em uma massa polar continental para saber se vai chover quando formos para a Praia da Joaquina no próximo Sábado não traz muito benefício no final das contas.

Assim, elencar as variáveis corretas e saber como utilizá-las na equação pode ser a chave do sucesso das estimativas.

No mundo dos projetos de software, felizmente, as mesmas regras se aplicam.

Introdução 3 – É bom não pular

Neste post - ou quasi-artigo - descrevo uma técnica muito interessante, que aprendi lendo sobre PU Ágil – uma das minhas metodologias preferidas – em trabalhos como os do Mike (COHN, Addison Wesley 2005), que é um grande cara!

Essa técnica foi estendida e fundida a conceitos da Feature Driven Development (FDD) [técnica de análise], da Domain Driven Design (DDD) [técnica de projeto] e da Extreme Programming (XP) [técnica de desenvolvimento], dando origem a uma proposta que é aplicada no nosso processo de desenvolvimento ágil gerenciado, o 3PUP (http://3layer.no-ip.info/confluence/3PUP).

A técnica se aplica a projetos de software de quaisquer tamanho, sendo mais beneficiados os maiores e aqueles em que poucas informações de requisitos e detalhamentos de baixo níveis estão disponíveis – ou seja, a maioria dos projetos ;)

Como já disse, ela vale-se de recursos do PU Ágil, XP, FDD e DDD, e deve ser executada por pessoas com conhecimento de Orientação a Objetos, UML e, principalmente, experiência na construção de Casos de Uso, como aqueles defendidos maestrealmente pelo nosso colega Alistair (COCKBURN, Addison Wesley 2000). Não obstante, precisa ter clientes “que abracem a causa” (conceito da XP).

Caso esses elementos não façam parte da sua sopa de letrinhas, sugiro desconsiderarem o resto do texto. Digo isso porque, se outros projetos, técnicas ou pessoas estiverem presentes (como analistas – desculpem o termo – ermitões da Análise Estruturada e do Mundo Relacional), é muito provável que a abordagem não funcione, e que acabem dizendo que ela é errônea ou inaplicável. Uma pena. Para eles.

O Cenário

Para ser mais realista, considere o ambiente: Uma empresa de varejo quer desenvolver um novo sistema. O sistema precisa ser “enterprise”, cobrindo o core do negócio da empresa e ser usável por sua matriz e filiais. Deve ser de fácil uso, utilizável por navegador web e com pontos essenciais com acesso desktop. Deve se integrar com sistemas legados, como RH, Orçamento e Custos, construídos em Clipper, Cobol e SAP, e usar várias bases de dados. Precisa ter dados online para todos envolvidos e atuar nas áreas de vendas, estoque, caixa, integração bancária e com operadoras de crédito; fazer projeções para vendedores, comissões, estoque, logística de armazenamento, faturamento, emissão de notas, contra-notas e integração com operadoras telefônicas, dando mensagens SMS em diversas situações. Idealmente, o sistema precisa ser extensível e com suporte para serviços futuros, com interfaces seguras para WebServices, SOA e mecanismos plugáveis externos, como relatórios de Business Intelligence. Tudo isso importando dados dos sistemas atuais e com os processos de negócio em funcionamento.

Completando, como política da nova gestão da empresa, e com verbas de fundos setoriais, a organização está revendo seus conceitos de trabalho, e busca otimização nos seus processos atuais, visando eliminar gargalos, pessoas e atividades burocráticas ou de baixo retorno. Em suma, ela é uma típica adepta do conceito de Engenharia de Processos, vogado nos anos 90.

Esse cliente chega até nós e nos indaga: quanto custa fazer esse sistema, e quanto tempo vai levar para estar completamente em operação?

A resposta não é simples, e estimar isso é como acertar se vai chover na Zona Leste de Cingapura na tarde do centésimo quadragésimo terceiro dia a partir de hoje. E claro, se a chuva será torrencial ou esparsa. Ah, e claro novamente, quantos metros cúbicos de água irão despencar nesse interim...

Mas independente desses detalhes, precisamos dizer algo para o cliente, caso contrário, ele não será nosso cliente....

Passo 1 – Identifique as Áreas de Negócio

Para que isso funcione, o cliente precisa abraçar a causa. E você precisa convencê-lo que isso é importante. Se você for perspicaz, vai conseguir isso. Se não conseguir, não adianta seguir daqui: esqueça do negócio, ou minta para o cliente.

Passo 2 – Mapeie os Fluxos de Trabalho

Mapear os fluxos de trabalho que ocorrem na empresa.

Passo 3 – Identifique as Atividades

Para cada fluxo de trabalho, identifique as atividades que o compõem, os atores envolvidos, responsabilidades, artefatos consumidos e produzidos e relações entre as atividades, incluindo restrições e segurança.

Passo 4 – Extraia os Casos de Uso

Para cada atividade em cada fluxo de trabalho, identifique os casos de uso relacionados a ela. Geralmente é um, mas nem sempre.

Passo 5 – Tipifique os Casos de Uso e Bordas

Identificar os casos de uso que serão implementados pelo software e aqueles que serão realizados manualmente. Para os que são realizados por software, marque os casos de uso manuais que se relacionam diretamente com ele – esses terão um tratamento especializado também (abaixo).

Passo 6 – Defina a Complexidade

Todos os Casos de Uso identificados precisam ter sua complexidade definida. Isso é essencial para a estimativa do projeto e pode ser feito com uma boa taxa de acerto sem muito trabalho de longo prazo. O post http://telasdecadastro.blogspot.com/2007/12/estimativa-de-projeto-por-pontos-de.html fala sobre isso.

Passo 7 – Agrupe os Semelhantes

Muitos casos de uso têm igual semântica. Em outras palavras, fazem a mesma coisa. Por exemplo, temos vários Casos de Uso para envio de emails (diversas áreas da empresa precisam enviar emails, embora cada uma o faça de forma singular) ou mesmo, muitos Casos de Uso fazem importação de dados externos (embora cada um importe um arquivo diferente ou o faça em uma base de dados distinta), etc. Mas fora isso, são semelhantes.

Passo 8 – Mensure o Esforço

Para cada tipo de Caso de Uso identificado na etapa anterior, compute o esforço relacionado usando a técnica Use Case Point (UCP). O mesmo post acima fala sobre isso. Preste atenção, eu disse para “cada tipo” de Caso de Uso, e não “cada instância” de Caso de Uso. Observe que, se um tipo tiver mais de uma complexidade identificada (o que é comum), você deve mensurar o UCP para cada uma das complexidades identificadas. Por exemplo, tem-se o Caso de Uso do tipo “Relatório Linear”, ondem foram identificados relatórios lineares (sem agrupamentos) complexos, médios e simples. Assim, deve-se obter a UCP para relatórios lineares complexos, médios e simples.

Passo 9 – Derive o Esforço

Nesse momento, existem centenas de Casos de Uso (ou mais). Mas, devido o agrupamento por semelhanças, existem apenas dezenas de tipos deles (ou menos – no 3PUP, nós temos menos de 20 tipos de Casos de Uso). Agora a regra é simples: somar a multiplicação da quantidade de tipos pela quantidade de instâncias de cada tipo, considerando as diferentes complexidades. Para um exemplo prático, considere que foram identificados 600 Casos de Uso de várias complexidades, os quais foram agrupados em 15 tipos diferentes (como CRUD, Mestre-Detalhe, Mestre-Detalhe Isomórfico, Relatório Linear, Relatório com Agrupamento, Integração De Entrada, Integração de Saída, Integração Bidirecional, Impressão Física, etc).

Um histograma desses Casos de Uso seria algo como:

Relatório Linear Simples.....: 7 UCP, 3 instâncias

Relatório Linear Médio.......: 18 UCP, 8 instâncias

Relatório Linear Complexo....: Nenhum

CRUD Simples.................: 2 UCP, 24 instâncias

CRUD Média...................: 8 UCP, 63 instâncias

CRUD Complexa................: 20 UCP, 33 instâncias

Mestre-Detalhe Simples.......: 12 UCP, 11 instâncias

Mestre-Detalhe Médio.........: Nennhum

Mestre-Detalhe Complexo......: 33 UCP, 4 instâncias

...e assim vai, sendo no total 600 instâncias de Casos de Uso.

Assim, basta somar a multiplicação da quantidade de instâncias de Caso de Uso pela UCP em cada item. Como resultado, tem-se o esforço total dos casos de uso do projeto.

Por exemplo, digamos que tivemos um total de 852.440 UCP (chutei). Uau, um sistema realmente grande. Eu diria, um ERP ;)

Passo 10 – Transforme UCPs em Horas/Homem

No Post acima, comento como transformar UCPs em horas de projeto. E isso é vital para a empresa que vai desenvolvê-los, bem como para a que vai comprá-los ;)

Felizmente, o processo é fácil. Mas, ironicamente (e infelizmente), é aqui que morrem a segunda parte dos candidatos.

Calcular UCPs é uma matemática que exige um esforço considerável e que pode necessitar também um histórico de projetos para que tenha sucesso (claro, esperamos que a sua empresa já tenha um bom Portfólio de projetos, e que esses reflitam a realidade...).

Usando a literatura básica, 850.000 UCPs são cerca de 42.500 horas de projeto, que deve dar algo em torno de 1,5 anos de trabalho em um time de 20 bons desenvolvedores. Claro, isso considerando uma arquitetura Enterprise já bem consolidada, extensível, homologada, praticada e.... documentada. E nem falei nas ferramentas de apoio: repositório versionado integrado com ferramenta de projeto, wiki, email, web-conference, fórum, etc. Tudo integrado, óbvio.

Mas bem, já temos os números: Tempo = 18 meses; Pessoas = 20.

Passo 11 – Monte o Cronograma

Com os valores definidos de tempo e pessoas, monte os cronogramas do projeto. Anexe seus custos e defina os marcos etapas-macro.

Coloque numa panela, chacoalhe e observe a espuma. Sirva para o cliente.

Moral da História

Em princípio, vocês podem argumentar que isso não é nada rápido de ser feito. E eu concordo.

Podem dizer que isso é complexo, que vai demandar um esforço enorme para ser realizado, que vai exigir uma “mini-equipe” somente para mapear os processos da empresa e que as pessoas necessárias para isso precisam de expertise em várias tecnologias e processos. E eu também concordo.

Da mesma forma, vocês podem argumentar que fazer o cliente “abraçar a causa” pode ser extremamente difícil e que os custos gerais para criar essa estimativa inicial podem ser, hum, absurdos?! Sim, também concordo.

Mas nada disso é diferente do que o velho Mike e outros gurus já não tenham nos avisado. Estimar tem um custo. Se não quiser esse custo, não estime. O gráfico abaixo mostra isso direitinho.

Porém, não estimar, ou ignorar essas variáveis é – ou geralmente será – muito pior. Fazendo isso, você simplesmente está fazendo como todos os outros. E aí, você não está usando matemática, e sim, brincando de chutar resultados.

A grande moral aqui pode ser assim resumida: Custoso não é estimar, mas sim, definir as variáveis corretas dessa equação e, claro, seus valores e variações aceitáveis. O resto, bem, o resto é matemática.

Num próximo post, eu coloco um passo-a-passo visual desse processo todo. Por hora, é isso.

quinta-feira, julho 17, 2008

O Primeiro Pipe a Gente Nunca Esquece

Acho que faziam uns quase 6 meses que eu havia lido sobre o Yahoo Pipes, mas nunca tive tempo para brincar com ele.

Mas como agora, com essa mudança de vida, as coisas devem ficar mais tranquilas, fui lá e criei meu primeiro pipe.

Impressão
Adorei. E olha que sou chato.

A interface é polida, funcional e o tutorial de 2 minutos do site é muito, mas muito bom mesmo.

Gostei das cores (que, ironicamente são ala Google) e, principalmente, das "minhoquinhas", que são justamente os pipes.


Funcionamento
Em suma, a idéia é ir conectando elementos através dos pipes para ter como saída um resultado de valor. hum, como assim?

Os elementos são coisas diversas, como Websites, Feeds, Operações, Formatadores e outros. Em suma, eles são mini-crawlers que vão nos endereços (URLs) de interesse e obtém informações, as quais são estruturadas para que...os pipes possam lê-las e...direcioná-las para outros elementos... e assim sucessivamente até que o freguês esteja satisfeito.

Uso
O pipe que eu criei foi bem simples, simplesmente apontando aqui para o TelasDeCadastro e extraindo os Feeds. Depois, reverti a ordem deles e filtrei para trazer os três últimos somente.

Isso foi feito em um formato totalmente visual, com um Drag And Drop bem consistente e sem nenhum a sensação de estarmos na web. Em outras palavras, o Ajax dos caras é bom.



Aplicação
Vou usar os pipes. E vou usar para montar e integrar recursos, juntando com o NetVibes (outro excelente), o Google Apps (razoável, mas que tende evoluir) e o nosso Jira e Confluence.

Assim, espero ter recursos centralizados e, melhor que tudo, úteis.

quarta-feira, maio 21, 2008

Load balancing com Tomcat e Apache

Introdução

Não é bem tema de telas de cadastro, mas posto igual porque tendo isso, então as nossas telas de cadastro poderão continuar funcionando por mais tempo...

Estou falando de load balancing, e especificamente, sobre load balancing usando o Apache HTTP e o (famoso) Tomcat.

Original no TheServerSide

Na prática, o artigo lido está no TheServerSide e ele, além de explicar o que é load balacing, dá exemplos de configuração muito úteis no dia-a-dia.

Aprendizado

Gostei do artigo porque fiquei sabendo que:

1. O mod_proxy é mais atual (e provavelmente melhor) que o mod_jk (que eu usava há anos atrás quando eu realmente fazia sistemas legais...)

2. Os algoritmos Round Robin de load factor têm variantes, habilitando o balenceamento por número de acessos ou tamanho das requisições.

3. Para preservar as Stick Sessions durante um desligamento programado, existe um "processo de shutdown" de servidores Real Workers, onde o objetivo é deslocar a carga de trabalho até que o servidor que será retirado do grupo não tenha mais (ou, se tiver, que esse número seja bem pequeno de) usuários ativos.

Conclusões

Faz anos que não pego nenhum trabalho que fosse preciso load balancing ou clustering de serviços.

E isso é uma pena, mostrando que os nossos Stakeholders não tem uma visão de como é importante disponibilidade e que como nosso conhecimento pode ir por entre os dedos quando não o aplicamos.

sábado, maio 17, 2008

Novo Layout

Vemelho & Preto
Depois de fazer alguns testes no meu blog adimensional, resolvi colocar um novo layout no blog das telas de cadastro.

Sim, estou usando o layout do Carls Mason, e tenho que admitir, embora não seja 100%, ele cai como um luva para o novo logo da minha empresa, a 3Layer Tecnologia.

Notícias Tristes
Na verdade, tenho notícias um pouco lacrimosas paras contar, mas, como eu me conheço bem, essas já são costumeiras em minha vida.

Sim, estou falando da negativa de incubação do projeto Merlin, na Incubadora Raiar do pólo tecnológico da PUC, em Porto Alegre.

Fazia tempos que esperávmos incubar a 3Layer Tecnologia lá, e estavámos com "altos planos" para isso.

Entretanto, acredito que a nossa profunda crença em Software Livre, e a nossa certa libertinagem no amparo financeiro tenham sido o elemento fatídico para o insucesso nessa empreitada.

Pelo sim, pelo não, não fomos escolhidos.

Tristes? Ah, ah!

Em nada.

Para quem conheçe minha história, sabe que não desisto facilmente. Meus planos pessoais vão muito além da temperança, boa vontade e capacidade de assimilação de certas pessoas.

Penso longe, sim - e é isso que me move.

Luto faz quase 8 anos nas idéias do Metagen, e agora do Merlin. Luto contra o tempo, contra as más nuançes da vida, do destino, da saúde, dos negócios, dos amores, do trabalho e os reveses (existe essa palavra?) diários.

Certa vez consultei um guru, e ele disse verdades. Atemporais, tenho que admitir. De momento, já acreditei. E hoje, hoje as confirmo.

Serão quatro anos, e não três, como agora ocorrem.

Assim, sigo à frente, e sem desistir, implico nele, o Merlin.

E a eles, que sintam o amargo.

sexta-feira, maio 16, 2008

Putz, copiaram o Merlin

Frameworks runtime para Telas de Cadastro

Quando iniciei o Metagen lá em 2001, achei que era uma coisa bem diferente. E era. Até a semana passada, para o mundo Java eu não conhecia nada do gênero.

Nas diversas pesquisas que realizei, encontrei mais de 20 projetos acadêmicos provando que a gerção de IU em tempo de execução já era possível lá nos anos 80.

Porém, frameworks de uso profissional, que não entrassem em “viajens” como álgebra relacional, formalismos maquiavélicos, linguagens conceituais ou gramáticas de outro mundo, bem, isso não tinha nada até o Merlin aparecer...

Metawidget

Mas agora os tempos são outros. E como me atraso constantemente em implementar o Merlin, a máquina anda e mais e mais pessoas começam a perceber que esse negócio de gerar código-fonte não tem nada a ver.

Bem por acaso, anteontem, nem não sei o que eu estava fazendo no branquelo, mas me deparei com um link de uma ferramenta chamada Metawidget.

Li alguns artigos e uma entrevista com o criador e só tenho uma frase a dizer: putz, copiaram o Merlin!

Funcionamento da bagaça

O framework do cara tem a essência do Merlin, mas trabalhando de outra forma.

Ele suporta além de beans Java, o famigerado XML. Assim, ele chama isso de “back-end”. Para ler esses back-ends, ele possui o conceito de Inspectors. Os inspectors usam (basicamente) reflexão e coisas to tipo para ler classes POJO, JavaBeans, Anotações ou XML.

E também dá para estender e criar inspectors para outros back-ends, tais como tabelas relacionais (pelo menos é o que o cara diz).

Para a geração, que também ocorre em tempo de execução, ele usa o conceito de Metawidgets. Você pode interpretar essas metawidgets como sendo um pattern Wrapper que encapsula e delega a widget do pacote gráfico em uso.

Assim, tal como o Merlin, ele também suporta diversas bibliotecas gráficas, como Swing, JSF, SWT e – isso eu achei legal – o Android.

Muito parecido

Depois de ler a documentação, baixei o fonte começei a olhar o negócio por dentro.

O Merlin possui a anotação @Caption, que serve para definir o label na tela, tendo suporte à internacionalização (i18n). A bagaça tem a @UiLabel.

O Merlin possui a anotação @Group, que serve para definir (sub)agrupamentos. O framework do cara possui a @UiSection.

O Merlin possui a anotação @Order, que serve para reordenar componentes na tela. O cara usa a @UiComesAfter.

O Merlin possui a anotação @Property, que serve para definir propriedades do controle de IU. O do cara tem a @UiAttributes.

O Merlin possui a anotação @Ignore, quando desejamos que um atributo de um objeto não seja mostrado na tela. A bagaça do cara tem o @UiHidden.

Os Inspectors do cara, são, praticamente, os Resolvers do Merlin.

Os Metawidgets do cara, são, again, os Renderers do Merlin.

Cada metawidget do cara estende a classe-base do pacote gráfico em uso. Por exemplo, ele tem uma metawidget que estende um JComponent para o Swing, outra que estende um UIComponentBase para o JSF, e outra que estende LinearLayout para o Android.

Observem que isso não representa limitações, pois permite que essas metawidgets (ainda não consegui decorar esse nome) sejam estendidas ou mesmo criadas do zero para pacotes gráficos diferentes. Ele tem um exemplo para o RichFaces.

Na prática, essas metawidgets recebem alguns parâmetros (que vêm das anotações, do objeto “inspectado” ou do código-fonte da aplicação principal) e passam-nos para a widget real no sistema. Como disse, é um wrapper com um pouco de deletage (ufh)...

Também olhei trechos de código e, pasmem (ou nem tanto), tem coisas praticamente iguais. Estruturas IF e blocos SWITCH parecem fazer as mesmas coisas em determinados momentos.

Outras funcionalidades semelhantes são o suporte à substituição de controles em tempo de execução, parametrização de layout, binding customizável (com suporte à JSR295) e mapeamento automático de tipos de dados para tipos de controle.

Para não dizer que estou mentindo, vejam:

//Metawidget renderizando um campo booleano e outro char

if ( "boolean".equals( type ) )

return new JCheckBox();

if ( "char".equals( type ) )

return new JTextField();


//Merlin renderizando as mesmas coisas

if (field.getClass() == FieldString.class) {

c = new JTextField();

} else if (field.getClass() == FieldBoolean.class) {

c = new JCheckBox();

}

Enfim, muito, mas muito parecido mesmo ;)

Parecido sim, mas não igual

Mas embora tenham os mesmos objetivos, os frameworks têm algumas diferenças sim. Evitando falar na configuração realimentada do Merlin, vou colocar algumas coisas que os distinguem:

1. POJO x Back-End: O Merlin foi projetado para suportar somente classes que sejam, no mínimo, POJOs. E nada mais. Nesse ponto, o framework do cara vai além, pois permite XML e outras coisas. Nós, no Merlin, vamos continuar afincos à nossa abordagem, pois dia após dia, a Domain Driven Design vem provando que é a melhor forma de fazer sistemas. Assim, nada de XML ou mundo relacional. Peço “sorry” aos que discordam...

2. Campos de lookup: Toda vez que o Metawidget encontra um campo de objeto que é uma referência para outro objeto, ele renderiza o objeto referenciado dentro da janela principal. No Merlin, o padrão é renderizar como um campo de lookup, ou seja, uma caixa de seleção. Acredito que o cara permita outro comportamento, mas não vi isso nos exemplos ou documentação. No Merlin, isso é feito via anotação ou novos renderizadores.

3. Renderização customizada: Nos exemplos do cara, para trocar um controle por outro (por exemplo, não quero o campo “nome” como uma caixa de texto, mas sim como uma caixa de seleção), o cara usa código-fonte na aplicação principal. No Merlin, isso também é possível. Poré, o mais fácil, rápido (e conveniente, pois entra para o sistema de histórico) é usar a anotação @RenderAs.

4. Inspectors x Renderers (again): No framework do cara, os inspectors são definidos na aplicação principal. Assim, se um bean tiver a anotação (do JPA) @Column.length mas não tiver o Inspector associado definido, então essa anotação é ignorada. No Merlin, o propósito é continuar usando ela para fazer coisas como, saber o tamanho que o campo deve ter na tela.

5. Binders: O Metawidget delega, assim como o Merlin, o processo de binding para frameworks de terceiros, como a JSR295. Mas para fazer isso, ele usa código na aplicação principal, ou via XML. No Merlin, usa-se essencialmente anotações, como @Binder, ou @RenderAs.binder.

6. Section x Group: São agrupadores de campos na tela. Não consegui ver detalhes maiores, mas acredito que as sections no Metawidget não possam ser renderizadas de maneiras diferentes. Por exemplo, no Merlin dá para fazer @Group.renderAs e também dá para fazer subagrupamentos com @Group.in.

7. Tratadores de eventos: Também não percebi suporte para o tratamento de eventos no Metawidget. Toda vez que o cara deseja colocar um tratador de evento em um controle, ele chama, tal como no Merlin, o método utilitário getComponent(String name). No Merlin, acredito que o conceito de Agentes seja muito mais fácil. Por exemplo @Agent(event=”focusLost”, action=”buscarPessoaPorCpf”)

8. Injeção, scripting, OCL e EL: Não vou falar tanto, pois o cara está, assim como quase eu estou, sozinho nessa história de criar frameworks. Porém, o suporte à injeção de recursos, previsto para o primeiro release do Merlin, é uma coisa obrigatória nos frameworks de hoje em dia. Ademais, para quem conhece Object Constraint Language e o poder que ela nos trás, não a dispensa tão facilmente. O suporte a scripting também é um recurso poderoso e não pode ser deixado de lado. Essas são coisas que estamos prevendo no Merlin e que o Metawidget parece deixar para um segundo momento, eu acho. Mas ele traz a Expression Language, e isso é bom. Tanto, que é previsto no Merlin.

Não conheçe? Tá bom...

Posso estar sendo tendencioso em minha análise (seráquáquáquá?). Mas não ocultei verdades em nenhum momento.

A única coisa que fico triste mesmo é que lendo o FAQ do projeto do cara, ele diz que não conheçe nenhuma solução do gênero. E isso é uma pena.

Compreendo que usando a língua inglesa o poder de penetração é maior. E até engines como a do branquelo acabam aumentando essa diferença. Mas o cara dizer que não conheçe nenhum gerador (ou seria, renderizador) semelhante é uma abscência total de informações. E não estou falando do Merlin, mas de coisas bem mais antigas, como o DRIVE, ITE, FUSE, AME, MASTERMIND, HUMANOID, UIDE, MECANO e, claro, o bom e velho Metagen...

Conclusões

Quatro.

Se temos concorrentes, é porque temos nicho de mercado.

Se a forma de implementar é quase a mesma, é porque estamos fazendo certo (ou estamos errando junto!).

Se os releases do Merlin demorarem a sair, não precisam sair mais.

E se não aprendermos inglês logo, de nada adianta ter releases.

sexta-feira, maio 02, 2008

Enfim ela: A JSR 317 - Java Persistence API 2.0 disponível para revisão

Veio hoje o email para o grupo, indicando que o Early Draft Review da nova especificação de persistência do Java está disponível para o público olhar e, claro, opinar.
É bem verdade que ela veio com o atraso de um mês (a previsão desse review era para o Abril passado), mas veio em boa hora igual.

Números e Improvements
Tenho inclinação inconsciente (olha eu usando palavras seguidas com as mesmas iniciais) para olhar as coisas e traçar comparativos. Essa JSR tem 299 páginas, que equivale ao número da JSR dos WebBeans, que está nas mão do hábil Gavin King.

Coincidências à parte, essa nova versão da Java Persistence API busca expandir os recursos da JPA 1.0, agregando features que há muito já deveriam estar disponíveis: melhorias na linguagem de query; expansões no mapeamento objeto-relacional (com ênfase para listas ordenadas, coleções de objetos embutidos e alguns outros recursos relacionados); padronização na engine de geração da DDL; contratos expandíveis para passivação e replicação de contextos de persistência; melhorias e uma maior padronização no gerenciamento nos estados dos entity beans e, principalmente, o suporte a validação dos beans.

Quanto à API Criteria (que diga-se de passagem, eu não gosto), esse primeiro draft nao trouxe nada de novo. Acredito que o grupo ainda não chegou a um denominador comum e, por isso, acho que esse capítulo somente deve vir no draft 2 desse documento.

Contraste
Não conheço niguém que usa JPA puro. Em outras palavras, não conheço ninguém que efetivamente homologou sua aplicação JPA com múltiplos frameworks sobre múltiplos banco de dados em múltiplos servidores.

Acredito eu - até que me provem o contrário - que isso é utopia mesmo. Ninguém em sã consciência (diga-se de passagem, os stakeholders) está a fim de arcar com isso, mesmo porque o ROI (Return Of Investment) de um trabalho desses sempre tende a zero.

Assim, o que acontece é que as pessoas (como eu) acabam usando implementações robustas (como o Hibernate - desculpem, mas Toplink não é um exemplo aqui) e deixam a equidade do JPA de lado.

Nesse sentido, essa revisão na JPA é mais impactante para os players que criam as implementações, e não nós que as utilizamos.

Ainda sem cache
Já era esperado, mas repito que eu ficaria feliz se o recuso de cache fosse disponibilizado na JPA.

Quem usa Hibernate, tem isso desde suas primeiras versões; antes com o ehcache, e hoje com o maravilhoso suporte dos caches clusterizados hierárquicos do JBoss :). Porém, essa feature ainda não deve vir tão cedo.

Ao meu ver, o recurso de cache na JPA somente deve vir lá pela versao 4 ou mais. Isso ocorre porque para termos um recurso de cache consistente, dependemos de protocolos de mais baixo nível, os quais estao na infra-estrutura de base do servidor EJB, tais como replicação e failover, lembrando que isso pode incluir recursos clusterizados ou não em ambientes transacionais e em modelos de rede muito atipicos. Quem usa JBoss se aproxima disso; quem usa outros servidores de aplicação, eu não tenho tanta certeza.

Obviamente, o recurso de cache poderia comerçar simplório (hic), como foi o ehcache lá nos idos do Hibernate 1.0 (há mais de 5 anos). Porém, acredito que isso esta mais para uma outra JSR, visto que envolveria mais do que apenas os entity beans. Enfim, ainda não temos.

Mais detalhes! Mais detalhes!
Vou ter que ler a especificação para saber exatamente o que mudou frente à JSR 220 (há, eu gostava tanto desse número). Somente depois, vou poder dar mais detalhes.

Sugiro para quem trabalhe na área, que baixe os 5MB do PDF e leia também. Afinal, a leitura é uma constante na nossa área.

Quanto ao release de hoje, bem, é o mundo evoluindo :)

sábado, março 29, 2008

Jira and Enterprise Architect Integration

Click here to see more about Jira, Enterprise Architect and Excel integrations.

Primeiro a imagem (porque eu preciso dela). Depois eu conto o resto :)


sexta-feira, março 21, 2008

Bem Vinda, JSR 303 - Bean Validation

Foi ontem que o Harold, do JCP mandou o email avisando que a Early Draft da JSR 303 está sob júdice do público. Sim, temos a primeira versão candidata da especificação para validação de beans, ou a Bean Validation.

Eu esperava essa JSR há tempos, e não perdi nenhum segundo a mais e fui logo imprimir as 43 páginas para me deliciar nesse fim de semana (sim, sou daqueles que não consegue ler PDF's).

Devido eu estar brincando (quase que literalmente) com clusterização no JBoss, eu não pude avançar mais do que as cinco primeiras páginas do documento. Logo, esse post também é um draft :)

Antecipo, porém, que quem ler a especificação não vai encontrar nada de (muito) novo em relação aos conceitos do Hibernate Validator, já nosso conhecido.

DDD, Anotações e Validadores
Na prática, a ênfase é seguir a Driven Domain Development (DDD), colocando todo o necessário nos beans da aplicação na forma de anotações. Essas anotações são resolvidas pelos validadores e, enfim, a aplicação cliente encarrega-se de mostrar as mensagens de erro produzidas.

Dispenso maiores comentários, pois, como disse, o Hibernate Validator é a base de tudo. Entretanto, registro que gosto de funcionalidades como a busca recursiva no grafo de objetos, a separação de validadores por grupos e o suporte de overriding através de XML (herança do EJB3).

Estilo
O Emmanuel (amigo do Gavin) está fazendo um bom trabalho sim. Mas quem lê o conteúdo desse draft, percebe logo que ela é bem mais baixo nível que uma JSR 220 ou 318 "da vida". Nada contra, mas são estilos de escrita diferentes. E aprovo esse estilo técnico também (embora em excesso ele possa ser tendencioso).

Pontos em Aberto
Alguns pontos estão em aberto na JSR. Ênfase para a escolha das anotações que serão as padrões (built-in) no framework e como será o mecanismo de overriding XML. Também o processo de bootstrapping parece não estar bem definido e o suporte EL não foi mostrado com carinho.

Até o dia 19 de Abril próximo (e claro, eu acredito que nessa data vocês podem colocar mais uns 45 dias) o comitê está aceitando sugestões para avanços nessa especificação. Assim, participem, meninos!

Pra quando e pra quem
A seção 2.3 do modelo 2.6 do JCP solicita a versão target da JSR. Nesse caso, visto que ela é em anotações (JSR 175), essa JSR deve funcionar apenas com JDK 1.5 ou superior. Isso caracteriza uma tendência óbvia - que o pessoal do Merlin (codinome do JDK 1.4, e não do gerador de IU...) está definitivamente indo para escanteio...

Quanto à inserção no Java SE, correm as línguas que o Dolphin (Java 7) deve trazer o pacote javax.validation junto. E isso é uma boa, pois nesse mesmo período deve estar chegando o Java EE 6 (JSR 316), a JPA 2.0 (JSR 317) o EJB 3.1 (JSR 318), o Swing Framework (JSR 296), o Web Beans (JSR 299) e outros releases importantes.

Sim, estamos em um limiar e 2009 promete.

sexta-feira, março 14, 2008

3PUP com acesso publico

Breve,

O 3PUP é uma parceira entre a 3Layer e a Pandorga, o qual visa a definição de uma metodologia unificada para desenvolvimento de sistemas enterprise com métodos ágeis e em plataformas diversas - atualmente Java EE e .NET.

Embora cada empresa (3Layer e Pandorga) vão implementar essa metodologia utilizando tecnologias e ferramentas próprias, a definição dessa metodologia é agnóstica em relação a isso.

Diversos conteúdos estão sendo disponibilizados nesse projeto, incluindo documentação textual, vídeos e, claro, muitos diagramas que cobrem todos os processos da metodologia.

Até hoje, esses trabalhos estavam operando internamente nas empresas, mas agora decidimos publicar seu conteúdo para Internet.

No link http://3layer.no-ip.info:6666/confluence/display/3PUP vocês podem ter acesso aos primeiros drafts que estão sendo colocadas na wiki.

Contribuições
Quem quiser contribuir com comentários e sugestões é bem vindo.

O status desse projeto é Alpha e um Estudo de Caso está sendo desenvolvido para um sistema de média complexidade para gerenciamento eletrônico de documentos (GED).

Acreditamos que uma versão estável dessa metodologia esteja disponível para o terceiro trimestre desse ano e, tão logo isso ocorra, deveremos estar homologando ela frente ao MPS Br.

quarta-feira, março 12, 2008

Finalmente, Top One

O Antes
Há quase dois anos postei o primeiro post do Telas de Cadastro. Naquela época, meu interesse era falar sobre assuntos relacionados a esses famigerados artefatos que consomem horas e horas de trabalho dos melhores programadores.
Nesse meio tempo, abordei assuntos diversos e, sempre tendencioso, insinuei o framework Merlin como uma solução para esses tempos perdidos.
Mas, enfim, o tempo passou. Vários posts foram colocados no ar e esse blog acabou dando origens a outros diversos, como o blog do Magoo, o blog do Merlin e alguns do mundo underground (embora sobre esses eu ainda não possa falar).
Nesse meio tempo, sempre procurei a expressão “telas de cadastro” no Google para saber em que pé anda esse blog. Ficava triste sempre pois, embora ele fosse Top Ten, ela não era Top One.

O Agora
Hoje, porém, após 68 posts, as coisas mudaram. Ao buscar “telas de cadastro” no branquelo, retornamos em primeiro lugar.
Fiquei muito feliz, uma vez que a política de grafos do Google nos deu a primeira colocação. Em palavras simples, de todas as páginas que sofreram o seu crawling (e acreditem, é muita coisa), a expressão Telas De Cadastro é Top One aqui.

O Futuro
Espero que eu consiga manter esse hit. Vou me empenhar em dedicar tempo para o blog e sempre que possível, achar assuntos de interesse para todos nós programadores.

Um abraço a todos e boas Telas de Cadastro.

segunda-feira, março 10, 2008

EJB 3.1, preparem-se

É, Bill Burke bem que tentou, mas ainda não será dessa vez que teremos “EJBs POJO”. Sim, estou falando do draft da JSR 318 que saiu no último dia de Fevereiro e que deve fazer parte da Umbrella JSR 316.

EJBs POJO podems ser vistos como classes Java normais, as quais simplesmente estão marcadas com @Stateless ou @Stateful e não precisam implementar nem estender nada. Seria algo como:

@Stateles class Clientes {

public double getSaldoConsolidado(Cliente c) {

// código EJB

}

Para os menos atentos, observem que um código do lado cliente seria algo como:

Clientes clientes = ServiceLocator.getInstance().lookup(Clientes.class);

double saldo = clientes.getSaldoConsolidado( new Cliente(1234));

System.out.println(saldo);

Sacaram? Pois bem, é justamente essa a discussão que o tio Bill puxou no seu site. Muita gente discordou, porque agumenta que o cliente teria acesso ao código da implementação do EJB (visto que não existe mais uma interface client para eles) ou que existiria um alto acoplamento entre lado cliente e lado servidor, ou...bem, vários argumentos!

Tio Bill enfatiza que isso seria um improvement, mas mesmo assim não pegou e, pelo menos nessa versão 3.1, ainda não teremos Enterprise POJOs...

O que teremos, então?

Mesmo não tendo EJBs realmente planos, teremos uma série de outras features, há muito aguardadas. Para ser enxuto, replico aqui o que diz a seção 1.2 da nova especificação (ainda em draft até o próximo dia 30):

  • Acesso direto de EJBs pela camada web dentro do mesmo EAR: A anotação @EJB já é uma commoditie (mesmo que sistemas homéricos tendem a subestimá-la) e é uma mão na roda para chamadas entre serviços dentro do container EJB. Ela encarrega-se de propagar o principal da chamada e todos os trâmites para gerenciamento das transações na aplicação. Porém, a boa nova é que agora ela pode ser usada diretamente pelo container web. Assim, um código de servlet pode injetar EJBs sem se preocupar com lookups por classes utilitárias. Claro, um certo overhead (?) de configuração pode ser necessário, a fim de garantir que as roles na web e nos EJBs sejam compatíveis. Também, devemos ter o cuidado disso tudo estar no mesmo Application Unit e temos o inconveniente de ter que usar (sempre) referencias locais e não podemos distribuir a aplicação em JVMs e containers separados (exceto ativando Trusted Connections). Mesmo assim, é uma benévola para os desenvolvedores web e, claro, essas limitações que eu comentei são coisas intrínsicas ao padrão atual e, com sorte, em um Java EE 7 ou 8 isso deve ser eliminado.
  • Empacotamento de EJBs dentro de arquivos WAR: Para mim, isso não é um grande benefício. Quem usa ANT ou Maven (ou qualquer outra ferramenta do gênero) não se preocupa muito nesse tipo de picuínha. Porém, pode ser uma diferença grande no ambiente de execução. Se o container for Java EE certificado, ele devera colocar para funcionar o .WAR integralmente, com as JSPs e também com os EJBs. Isso me lembra muito o Tomcat com o EJB Embedded e parece que os caras estão começando a misturar as coisas. A palavra Web ARchive deveria exprimir a função do pacote, mas pelo jeito ela também agora é outra commoditie. Não li muito sobre as entranhas disso ainda mas, enfim, essa tendência de reduzir artefatos está mesmo em voga.
  • EJBs Singleton: Isso me deixa feliz. Mas em parte. Primeiro, feliz por ter singletons em EJBs. Aos puristas, vão reclamar que isso pode ser pesado e que pode trazer outros malefícios, como afunilamento de chamadas de clientes e tal. Mas isso é um engano. Quem nunca tentou fazer um código maluco para simular (sim, simular) singletons em EJBs que atire a primeira pedra! Se não tentou ainda, é porque não teve que passar por mal bocados. Singletons em containers é uma tarefa difícil, e em ambientes de alta concorrência a coisa pode render boas noites de pizza e coca-cola. Poder anotar um EJB com @Singleton, e indicar ainda se ele vai ter dependências de inicialização, comportamentos @ReadOnly, @ReadWrite ou ainda se vai ser gerenciado manualmente (tal como os famigerados modelos BMP para os Entity Beans) é, sem dúvida alguma, um ponto positivo nesse release da especificação. Porém, fico triste de os caras não terem ido além (sim, talvez eu seja muito perfeccionista mesmo). Singletons são garantidos por container e, assim, em ambientes clusterizados cai novamente para o desenvolvedor a tarefa de comer pizzas nas madrugadas.
  • Timers criados automaticamente: Isso é outra coisa que eu aprovo. Até a versão 3, tínhamos que explicitamente ativar um EJB de timer para, somente então, ele começar a trabalhar. Agora, com as features de @Startup, as coisas mudam de figura. Em tempo de deployment o container já se encarrega de localizar e ativer os timers conforme nossa necessidade. Nada mais de consoles com métodos admistrativos (muitas vezes operando com sistema de autenticação diferenciados e avessos aos interceptadores padrões do sistema) para ativar essas pecinhas!
  • EJBs Assíncronos: Isso só pode ser herança do AJAX. Mas é uma herança boa, ao meu ver. Também, até a versão 3, toda chamada para um EJB é síncrona, o que implica que o cliente (ou melhor, a thread chamadora deste) deve ficar parado até que o retorno do método de EJB ocorra. E isso pode ser um tempo perdido muito grande. Soluções seriam usar AJAX (e fazer uma sincronização manual no lado cliente) ou lançar mão de JMS para esses métodos mais demorados. Agora, poderemos usar em tranquilamente a API java.util.concurrent.Interface Future, que já existe no Tiger há muito tempo... Com isso, o cliente deixa de ficar ocioso e pode trabalhar tranquilamente até que sua requisição EJB tenha uma resposta. Como Future é um objeto criado pelo servidor e retornado para o cliente, o cliente tem um link do servidor para, tanto monitorar o momento em que uma reposta ocorra, tanto para...cancelar sua requisição. Isso mesmo, diferente de AJAX, que o cliente deveria lançar outra requisição de EJB (e fazer uma lógica maluca para garantir o funcionamento de requisições Stateless no pool do servidor) para efetuar o cancelamento da chamada original, agora Future encapsula tudo para nós e deixa tudo transparente. Imaginem as possibilidade, meninos...
  • Profiles: Lembram do Java ME e seus profiles? Pois bem, agora a Java EE está nessa onda também. A idéia é que, como a tecnologia Enterprise do Java está crescendo muito e, por isso ela pode facilmente se tornar um canhão para matar moscas, a própria especificação já cuide para criar subconjuntos de componentes para os containers. Seria como ter um container Web, um container Web com EJB Light, um container WebService com EJB, etc. Na prática, isso já vem sendo implementado pelos containers atuais, como o JBoss, que traz seus diretórios minimal, default e all. A diferença é que agora a Umbrella estaria ditando quais são esses profiles e o que deveria existir dentro deles. As picuinhas entre os prós e contras é grande, sendo que uns argumentam que isso não deve ser preocupação do JCP ou que abriria brechas para meias-certificações, algo como um provider certificar somente parte do seu servidor e o restante deixar numa versão mais antiga, ainda não homologada pelo TCK. Na minha opinião, tanto faz.

Conclusões

Conheço muita gente que ainda nem usa o JDK 5. Muitos também são avessos às anotações, tipos genéricos e conceitos um pouco mais avançados, como Resources, Múltiplos Classloaders, WebServices, etc. Para todos eu digo: corram (bastante), rapazes!

Java evolui a passos largos, e se a tendência é seguir novidades oriundas do pessoal do Spring, Ruby, Smalltalk, Groovy e outros. Assim, um ajuste pequeno como esse na especificação EJB deveria se passar como manteiga sobre o pão.

Para mim, todas as features são bem vindas e, para ser sincero, espero muito mais para os próximos releases. Se a idéia do tio Bill de usar EJBs POJO não vingar, quiçá me deixem usar a mesma anotação para EJBs locais e remotos. Só isso já seria uma mão na roda.

segunda-feira, fevereiro 25, 2008

Quem são eles?

Para quem programa (principalmente com Java), já deve ter lido muito material produzido por eles.

Da mesma forma, já deve ter utilizado frameworks que eles construíram e se maravilado com conceitos básicos de servidores de aplicação (e aplicações em si) que estas peças definiram.

Mas se na literatura os nomes são familiares, na foto, quem são eles ?




Especificações Executáveis via wiki

O mundo é realmente grande. E as formas com que as coisas podem ser feitas variam de tal maneira que, para os que estão distantes, elas simplesmente parecem inimagináveis. Estou falando das Especificações Executáveis da GreenPepper, as quais podem ser utilizadas sobre o Confluence e o Jira, ambos da Atlassian. E o bom é que isso pode fazer parte do 3PUP.

Vamos a um cenário:

1. No Confluence, em formato wiki, nas etapas de análise e projeto, o analista especifica seus requisitos e casos de uso;
2. Para cada requisito, ele determina quais são as suas regras de aceitação, também na própria wiki;
3. No Jira, as issues são criadas e ligadas às respectivas especificações da wiki;
4. Os desenvolvedores resolvem as issues, tal como define o cronograma do projeto;
5. Concluídas, as especificações vinculadas às issues podem ser automaticamente executadas, na própria wiki;
6. Os resultados dos testes podem ser visualizados diretamente ou então publicados para fins gerenciais.

Greepepper, a empresa

Primeiro, um parabéns para os caras. Greenpepper (pimentas verdes) é uma empresa focada em processo ágeis, tal como a 3Layer. Experientes no ramo, eles têm plugins para o Atlassian Jira, de forma que a condução da gerência de projetos através detse software possa ser facilitada.

Semana passada solicitei uma licença Open Source para a nossa instalação do Jira e fiquei estupefado em receber um reply (humano, diga-se de passagem) com a licença solicitada em menos de 10 minutos! Sim, os caras são rápidos.

GreenHopper, o plugin

Muitas empresas julgam ter processo ágeis. Porém, disso especulo, pois dando aos extremos, os meios são geralmente penalizados. Uma frase não dita em uma ata de reunião não escrita em um documento não protocolado pode ser o estopim para centenas de horas mal ocupadas em um projeto. E acontece, não duvidem.

O mesmo vale para requisitos mal escritos, ou casos de uso mal testados. E em processos evolutivos, a tendência é que os desvios aumentem a cada interação. Mas como manter especificações e testes atrelados, sendo que entre eles diversas etapas de projeto, interações e pessoas estão envolvidas?

A resposta pode não ser total, mas o conceito que a fundamenta, se bem explorado, é capaz de promover a completude ao questionamento: são as Especificações Executáveis. E é justamente isso que o plugin da GreenPepper oferece para nós.

Um exemplo

No link http://www.greenpeppersoftware.com/confluence/display/GPO/Writing+my+first+Executable+Specification vocês tem mais detalhes. Aqui, reproduzo o essencial:

Digamos que o analista especifique uma operação de soma, e dê alguns exemplos de entradas e saídas esperadas: 2 + 5 = 7; 1 + 3 = 4; 80 + 1 = 81.

Uma vez que as tarefas relativas a construção essa operação de soma sejam concluídas por um programador, seria interessante testá-la; não?

JUnit e outros frameworks caem bem. Mas notem que foi o analista que definiu as operações e os testes aqui. E que nem sempre ele vai conhecer bibliotecas de baixo nível, como o JUnit.

Da mesma forma, obrigar (e garantir) que os programadores acessem a wiki e criem JUnit’s consistentes com as especificações é uma tarefa herculóide (ou insana, devido à redundância).

E o problema piora, pois o analista pode ter errado nas versões iniciais de suas especificações; pode tê-las evoluídas, melhoradas; aumentadas e, no pior dos casos, estendidas – agora o sistema precisa suportar multiplicações. Nesses casos, como garantir a sincronia entre as especificações e os testes?

A resposta para tudo isso se resume em executar as especificações na própria wiki.

Seja um formato simples, como abaixo:

Essa entrada pode se executada diretamente pelo plugin da Greenpepper e ter saídas como:

Notem que o resultado do último teste falhou, retornando 80.

Da mesma forma, podemos estender a nossa tabela, para suportar novas funcionalidades, como:

Observem que podemos modificar em alto nível as especificações e ainda tê-las integradas ao restante do projeto (controle das issues) e à implementação (código-fonte) sem maiores dificuldades.

Funcionamento

Não me peguei aos detalhes, mas pelo que percebi, cada um desse testes (e tem vários tipos, incluindo o suporte à interação, condições, coleções, etc.) é atrelado a uma fixture, a qual aponta para a classe ou pacote de teste. Essa fixture é importada na wiki, de forma a ser o elo entre o código-fonte e especificação. O plugin GreenPepper se encarrega do suporte, permitindo que todo o projeto se mantenha coeso e sincronizado.

Conclusões

Primeiro, obrigado à GreenPepper por nos ceder a licença Open Source para o Merlin. Segundo, adoro automação. E, considerando que o 3PUP almeja ser uma metodologia ágil sem colocar em detrenimento os meios (e daí o motivo de ele ser um desafio), o conceito de Especificações Executáveis é uma funcionalidade muito interessante.
Deus salve a Internet, a qual encurta distâncias e permite que o inimaginável aconteça.

domingo, fevereiro 10, 2008

Jira e Google Calendar para o 3PUP

Aos que não sabem, a 3Layer Tecnologia está unindo forças com outra eminente empresa na área de TI para definição de uma metodologia unificada para o desenvolvimento de sistemas enterprise, a qual visa abordar plataformas Java EE e .NET. O nome desse projeto é denominado 3PUP e deve se transformar em produto ainda nesse ano de 2008.

Fora os trâmites internos que rolam desde início de janeiro, inúmeros trabalhos são consequência (já disse que é difícil usar trema no meu teclado - parem!) dessa iniciativa. E destes, vários são relativos à otimização; claro!

Otimização
Os que me conhecem, poder arguir (sem trema!) que tenho certas prerrogativas natas, sendo um cara (extremamente) cético, metódico, crítico, perfeccionista, incisivo, perspicaz, objetivo e, por vezes, interpretado como um visionário e lunático. Fora esses adjetivos, os quais, dependendo do meu estado de espírito eu possa concordar ou negar definitivamente, considero que, se eu pudesse escolher uma palavra que me traduzisse, esta seria otimização.

Não vou nem comentar sobre o DTOptimizer, que nem está acabado ainda mas, realmente, para tudo que vejo, penso que deve existir uma forma mais fácil de ser feito.

Jira para automatizar
No passo que anda o 3PUP, temos definido o fluxo de levantamento, validação, catalogação e publicação de requisitos, o qual é composto (se a Summer não está me enganando agora) de 16 atividades, as quais envolvem analistas, usuários líderes, projetistas, arquitetos (e, eventulamente gestores, gerentes, designers, programadores e consultores) - todos papéis definidos no grande workflow em desenvolviemento.

Como otimização é a palavra-chefe da 3Layer, e considerando que com a "benção" da Atlassian, podemos utilizar gratuitamente a versão Enterprise do Jira, decidimos que todo o fluxo do 3PUP será automatizado por este software.

Google Calendar para agendar
O Jira é maravilhoso (e acredite quando digo isso, pois veja bem os adjetivos que me descrevem acima!). Porém, tem coisas que só o branquelo faz. E uma delas é o Google Calendar.

Sua interface polida, funcional, de uso horizontal e seus reminders SMS são uma "mão na roda". E esta é o estepe do Jira :)

Ao juntar à equação do 3PUP um cara extremanente chato, um software flexível como o Jira e uma atitude como o Google Calendar, o resultado só pode ser um processo ágil, automatizado e extremamente transparente - em palavras simples, que nem o maior projeto de software em desenvolvimento no Brasil possui (um dia eu falo sobre isso - ainda não, desculpem).

O sábado
Mas para essa automação, esforços técnicos são necessários. E assim, hoje, passei o dia brincando com a API do Calendar. Fiquei feliz "pra caramba" com a telinha ao lado. Tanto, que até penso em escrever um artigo pra Java Magazine. Mas isso ainda vamos ver...

Confluence para registrar
Porém, não basta automatizar o processo e fazer agendamentos. Precisamos registrar as coisas.

E como a 3Layer adora softwares horizontais e formatos .online, nada mais óbvio do que uma ferramenta de wiki atrelada ao processo.

Nesse sentido, novamente com a graça da Atlassian, o Confluence vem complementar o 3PUP, garantindo pautas e atas integradas, atualizadas e corretamente distribuídas. E óbvio, tudo automatizado.

EA, Subversion, FishEye, CruiseControl e Gmail
E eu poderia continuar dizendo que temos em desenvolvimento a integração do projeto, suas tarefas e recursos aos status, pacotes e elementos como Casos de Uso, Requisitos (...) e os baselines da (outra excelente ferramenta) Enterprise Architect ao processo. Tudo gerenciado pelo Subversion (já disse que adoro ele também?) e com a feature da integração contínua garantida pelo CruiseControl.

Para complementar o pacote, o Gmail, que avisa, deliveraba (acabei de criar uma palavra! - ainda estou rindo, acreditem!!!), armazena e compartilha informações "às pancas" para os envolvidos.

Entenderam?
Não sei se quem leu o post entendeu alguma coisa. Mas é exatamente isso que estamos fazendo. Brincando de fazer software de qualidade, barato, robusto e em tempos inimaginávies para qualquer outra empresa conservadora. Viva as diferenças! Viva o 3PUP!

domingo, janeiro 20, 2008

Sim, temos que ler

Assino o InfoQ, recebendo semanalmente cerca de 10 a 15 feeds sobre tecnologias diversas, principalmente nas áreas de processos ágeis, java e linguagens dinâmicas, como Groovy, Ruby e as primas pobres, como o Beanshell.

Claro, eventualmente, alguns lixos aparecem e, mesmo que não exista um botão "Ban" como no LastFM (sim meninos, foi ali que achei as fotos para o livro de Java EE...), o problema se resume em 30 segundos com uma rápida visualizada no abstract do artigo.

Entretanto, alguns feeds parecem bons, e como o tempo é curto, nada mais posso fazer além de marcá-los como featured no Gmail para uma leitura posterior. Porém, como a tendência é acumular as coisas, chega-se o tempo do flush e as coisiboas tem que ser lidas. Então, resumindo (bem) essa pilha de dois meses:

Elvis Operator
Esse é do Groovy, e adorei ele. Não pelo nome (que é engraçado mesmo), mas pela simplicidade e claro, pela performance. Resumindo:

Código Java:

String foo;
//brinca com foo
//...

//retorna o valor de foo

String getFoo() {

return foo;
}
//imprime foo...
void printFoo {
System.out.println( getFoo() != null ? getFoo() : "Foo é Nulo" );
}

Qual o problema? Hum...não sei :) Bem, primeiro, você está quebrando a premissa DRY (Don't Repeat Yourself). Segundo, getFoo() está sendo chamado duas vez. Não apenas performance pode estar envolvida, mas se esse método tiver um comportamento extra (com incrementar um contador, incluir, remover, alterar, etc, etc, etc) além de buscar um mísero valor (...), você está em maus lençóis e teria que usar uma variável auxiliar no código. No mínimo, chato. E, se você fosse ranzinza como eu, teria ainda mais problemas, como falsos hits em analisadores de código (PMD, etc), linhas e linhas de resultado em um Control+Alt+H no Eclipse, etc, etc, etc.

Tá, mas e o Elvis? Ok...

Código Grovy (1.5+):

//não vou repetir o código anterior :)
//imprime foo...
printFoo {
println { getFoo()?:"Foo é Nulo" }
}


Antes que você exclame Que que é isso?!, leia mais sobre o Elvis operator em What's New in Groovy 1.5. Garanto que vai gostar.

Enhanced Loop
Para os amantes do loop otimizado do Java 5, abaixo, a versão grooviana:

//varre o intervalo especificado

for(e in 0..9) println(e)

//e claro, o "e" pode ser qualquer coisa...
def list = ["uma string", 10, 2.2, null, new Person(name:"Marcelo"), this]
for(o in list) println(n)

DSL (Domain Specific Languages)
Pra quem tá por fora, vou resumir: Java é uma linguagem de uso geral, assim como C, Pascal e qualquer outra linguagem de terceira geração que todos nós mortais estamos acostumados (sim, pra variar SQL é tão podre que está no meio do caminho de novo...). Uma DSL é algo (interpretem como algo mesmo) mais próximo do...hum...domínio do problema. Tá, vou dar um exemplo real (em groovy):

"...ah, o somatório das horas no projeto pode ser feito com cálculos baseados em dias, horas, minutos, semanas, work days, non stop days e um monte de variações, suportando ainda intervalos, valores quebrados e combinações entre esses e outros elementos..."

Bom, dá pra notar que o usuário está falando do cálculo de horas em projetos (talvez de TI) e que, se você for programador e quiser implementar isso (hum, em Java) ficaria maluco fazendo classes genéricas, construtores, conversores, adaptadores e uma infinidade de métodos e classes utilitárias de suporte para...calcular as horas do projeto :)

De novo...código groovy:

//sim, funciona...
horasDoProjeto = 3.dia + 2.hora + 12.segundo + 4.workday + 2.nonstopday - 14.diaParado
//e, claro...
custoDoProjeto = horasDoProjeto.hora * 5.dolar


Para detalhes disso, o post do Joe's é uma leitura divertida.

Putz, já são 19:07
Sim, falei só do Groovy, e mesmo assim levei mais de 1h par escrever esse post! Estou ficando lerdo mesmo. Quando der, vou comentar os outros featured itens do meu Gmail...