Desenvolvimento

24 jun, 2013

Por que qualifiers OSGi nao estão funcionando

Publicidade

No meu artigo anterior, eu argumentei que a decisão de não apoiar faixas de SNAPSHOT no OSGi foi uma oportunidade perdida para a plataforma, talvez uma que vá limitar sua adoção no futuro. Apesar de várias críticas (em grande parte argumentando a partir de um ponto de não ter usado Maven e seu esquema de versionamento SNAPSHOT), eu decidi ver qual era a real situação.

Os argumentos de “Talvez isso possa causar um problema” realmente não parecem ser confirmados pelo repositório Maven, que tem mais de 400G de artefatos versionados que passaram pelo processo de SNAPSHOT durante o desenvolvimento e raramente, ou nunca, têm algum problema de código versionado. (Isso não quer dizer que um erro não pode acontecer, mas é fácil o suficiente publicar um novo ativo com uma nova versão do patch, se necessário, como tem sido feito, ocasionalmente, como os lançamentos javax.jms).

O problema com a existência do build qualifier do OSGi é que isso significa que os desenvolvedores do Eclipse realmente não tomam cuidado com o versionamento de código de forma correta. Em vez disso, o processo de construção apenas despeja pacotes recompilados, muitas vezes sem um solavanco correspondente ao numero da versão, quando necessário ou solicitado.

Por outro lado, JARs publicados no repositório Maven (muitos dos quais já são pacotes) graças ao maven-bundle-plugin e a outras ferramentas de compilação) têm a versão correta definida fora do espaço do SNAPSHOT – dentre eles há um processo que impede a publicação de lançamentos SNAPSHOTs para Maven central ou (o “Repositório Central” – “Central Repository), como é agora conhecido. Isso significa que uma vez que um pacote é publicado com o número de sua versão final, e suas hashes SHA correspondentes são geradas, não podem ser alterados. Pacotes imutáveis são bons.

Então, eu dei uma olhada no repositório composto do Eclipse Indigo (ou seja, incluindo 3.7.0, bem como 3.7.1 e 3.7.2) para ver quão disseminado era o problema. O resultado surpreendeu até a mim. Dos 9 mil pacotes que compõem o Indigo 3.7.0-3.7.2, mais de 950 foram publicados com diferenças apenas no qualifier. Isso, acima de tudo, parece violar tanto a intenção como a prática de bons processos de versionamento. A especificação de versionamento semântico requer a versão do patch para ser colidida quando o pacote for alterado, assim como as recomendações OSGi e as do Eclipse. Claramente isso não está acontecendo, quando mais de 10,5% dos pacotes do Eclipse – incluindo muito dos pacotes “centrais”, como PDE, Equinox e Core – não estão batendo versões adequadamente.

Quando eu tuitei sobre essa descoberta, BJ Hargrave da IBM e o diretor do OSGi afirmaram que essa versão do OSGi indicada estava funcionando bem, e que os pacotes tinham sido “simplesmente reconstruídos”. Parece que está faltando madeira para as árvores; se não houve alterações, por que ele precisa ser reconstruído? Por outro lado, se houve mudança, por que não saltar a versão?

Eu analisei o pacote admin do framework Equinox, que foi reconstruído, e as diferençcas entre eles (org.eclipse.equinox.frameworkadmin.equinox_1.0.300.v20110506.jar vs org.eclipse.equinox.frameworkadmin.equinox_1.0.300.v20110815-1438.jar). As únicas mudanças nesse pacote foram um carimbo do Bundle-Version, o elemento Eclipse SourceRefernces , e uma mudança na api_description para apontar para um novo número. Não houve alteração no próprio pacote de código. Portanto, esse pacote de 60K é completamente sem sentido quando comparado ao seu antecessor; são apenas bits extras na instância Eclipse de todos, nos servidores de atualização do Eclipse e no uso de banda larga adicional ao atualizar. Ok, então 60K por si só não é muito, mas se, como argumenta BJ, todos esses 950 pacotes são “apenas reconstruções”, qual o objetivo?

Eu argumento que essa não é apenas uma falha no processo de construção, mas também no versionamento do OSGi. Se eles foram construídos utilizando versões de estilo SNAPSHOT, a versão teria sido adiada para 1.0.300 em maio de 2011, e somente se solicitado uma 1.0.301 seria necessária. Desde que o processo, quando lidamos com versões de estilo de -SNAPSHOT, seja lançado, então ficaria claro se as alterações foram necessárias, e o timestamp não teria sido necessário. Você não consegue vários lançamentos do Felix onde “ele acabou de ser reconstruído”, por exemplo.

O mesmo efeito parece ser visível, com as diferenças org.eclipse.pde.runtime_3.4.201; novamente, parece ser devido a um commit da api_description, Bundle-Version, Eclipse-SourceReferences, e assim por diante. Mais uma vez, a utilidade do pacote qualifier é mascarar o verdadeiro problema; há um processo de construção que está atualizando tags em arquivos via Eclipse-SourceReferences e api_description desnecessariamente, em seguida, liberando as mudanças no site de atualização. Isso também causa um efeito indireto do desempenho do repositório P2, que armazena todas essas entradas duplicadas e é consultado sempre que o Eclipse é atualizado; pior, enquanto os bits dos JARs duplicados são baixados apenas uma vez (no tempo de instalação/atualização), os metadados P2 são atualizados mesmo quando você não instala esse pacote.

Tendo uma extensão .qualifier na qual você pode girar um novo build de um pacote de cada vez, mascara o problema real, que é possível gerar um novo pacote com possíveis mudanças, sem alterar o número de versão. Além disso, se você construir uma nova versão, ela será automaticamente pega por P2, mesmo que o conteúdo seja quase idêntico (como as mudanças acima mostram). Utilizar a versão mais recente é necessário durante as fases de desenvolvimento – fase SNAPSHOT em termos Maven – mas, uma vez que o conteúdo é bloqueado, não há necessidade de sempre reconstruir uma nova versão.

Finalmente, há mudanças que deveriam ter exigido uma modificação no número de versão que – como os outros acima – seria disseminada através da rede. Os pacotes org.eclipse.emf.ecore (2.7.0.v20110912-0920 e 2.7.0.v20120127-1122) mostram uma mudança na classe (pública) org.eclipse.emf.ecore.resource/impl/URIHandlerImpl, embora, na verdade, isso corresponda a nenhuma alteração significativa na própria fonte de código.

Todos esses erros foram escondidos em virtude do processo automático de construção rápida (em essência) de qualifiers permanentes do SNAPSHOT do sistema de construção do Eclipse PDE. Mesmo se não houver mudanças, a reconstrução de um pacote provoca uma colisão no qualifier, que por sua vez leva a downloads adicionais até mesmo onde não é necessário. Isso não aconteceria se o OSGi suportasse diferentes versionamentos do -SNAPSHOT, porque o bump-to-prod (batida de produção) teria identificado que não era necessário reconstruir esse pacote, já tendo sido publicada uma versão especifica.

Infelizmente, embora o apelido de “acesso precoce” tenha sido concebido para tornar as especificações disponíveis antes da publicação, não há nenhuma maneira de isso ser alterado neste momento. Ironicamente, foram os versionamentos diferentes do snapshot que obrigaram a liberação de versão 5 do OSGi; agora que os lançamentos do SNAPSHOT foram removidos, há pouca razão para ainda visualizar isso como R5, em vez de uma versão R4.4.

***

Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://alblue.bandlem.com/2012/04/osgi-qualifiers.html