sexta-feira, 13 de dezembro de 2013

YOW Sydney 2013 - meu resumo

Não é sobre Java, nem maven, mas né?

http://sydney.yowconference.com.au/

  • Agile é padrão de mercado. Simplesmente. Nem existe outra opção. Ou é, ou é. 
  • Devops "is a thing".
  • Tudo aponta pra functional programing. Se vc não está nessa, é bom começar. 
  • Netflix é todo na nuvem. Facebook todo em datacenter

As minhas palestras e apresentações preferidas:


Computing Like the Brain: The Path to Machine Intelligence (Jeff Hawkins)

Simplesmente fantástica.Um simulador do neocortex dos mamíferos - uma enorme e complexa máquina de casar padrões. Com isso, o mesmo software pode ser usado para detectar anomalias em instancias da amazon ou criar dicionários.


Safety Not Guaranteed: How Successful Teams Ignore the Rules to Create Successful Products (Jeff Patton - @jeffpatton)

Combina muito com o que eu acredito do que é agile. Autor da frase "No ciclo waterfall, a responsabilidade desce e a culpa sobe!", e é total verdade. Testers culpam devs, que culpam analistas, que culpam cliente, que culpam... é.

Aqui os slides


Five Years of DevOps: Where are we Now? (Michael T. Nygard - @mtnygard)

Uma tecnologia leva uns 10 anos desde early adopters até ser padrão de mercado.
Daqui pra frente vai ter gente se desinteressando, gente entrando de gaiato, mais uns cinco anos e deve ser padrão. Tem muita gente querendo dar solução mágica, que não existe. Mas ainda leva um tempo, umas desilusões pra coisa se consolidar e sair desse estrelismo.


Solving the Hard Problem of Concurrency (Joe Albahari - @linqpad)


Concorrencia tem que ser tratada com FutureTask ou similar. Nada de sair disparando thread e dando wait.


The First Monad Tutorial (Philip Wadler - @PhilipWadler)

É literalmente o primeiro tutorial de Monad em Haskell ever da história da humanidade, reapresentado. 22 anos depois. Scala e seus Ms e monads (esse 'a' tem som de 'a' mesmo, se fala como se fosse /monád/).

Autor da frase "ÓBVIO que vcs conseguem lidar com matemática, vcs desenvolvem em Javascript!!!"
Simplesmente fantástico. A hora que ele tira a camisa e por baixo tem uma camiseta do super lambda simplesmente é pra morrer de amor.


What Colours is Your Backlog? (Philippe Kruchten - @pbpk)
Lidando com mudanças de arquitetura, tech debt e bugs no seu backlog.

sexta-feira, 1 de novembro de 2013

PROTIP: prerequisites não são herdados (e não é pro que provavelmente você acha que é)

Um dia você decide que quer que todo mundo que builda o seu projeto tem que usar maven 3.0.5
Você lembra que o maven tem um troço chamado "prerequisites", e pensa "uhuuu, vou colocar no meu parent pom."


    3.0.5


Seria genial e simples, né? Já pensou ainda se TODA sua empresa usa o mesmo parent pom. Pensa, forçar a companhia toda a usar no mínimo essa versão do maven, que massa que ia ser?

Esse é o maven cuidando de você


SÓ QUE NÃO!

Fica a dica, essa tag não é pra isso. Serve apenas para, quando você construir um plugin, você marcar qual é o maven mínimo. Não serve para definir ambiente do desenvolvedor do seu projeto.
Essa tag não é nem herdada por qualquer outro módulo. 

Se você quer garantir a versão do maven em desenvolvimento, você usa o "enforcer plugin".


http://maven.apache.org/enforcer/maven-enforcer-plugin/faq.html

The prerequisites tag was designed to be used by tools like plugins. It will work for regular projects, but it isn't inherited to their children. If it is set in a parent reactor, then Maven will do the check. However if one of the children are built, the check is not performed. The enforcer plugin is designed to allow centralized control over the build environment from a single "super-pom", and to allow greater flexibility in version specification by supporting ranges.

#fikdik

terça-feira, 29 de outubro de 2013

Declarar "repositories" no seu pom faz um tigre chorar na China


Totalmente roubado de:
http://blog.sonatype.com/people/2009/02/why-putting-repositories-in-your-poms-is-a-bad-idea/#.Um5hYiS9CAI


Adicionar os repositórios no seu pom.xml ao invés do settings.xml pode ser catastrófico a longo prazo. Principalmente se você espera que pessoas utilizem esse artefato como uma dependência do projeto delas. Quando e se a URL sair do ar, as pessoas não vão mais conseguir utilizar as versões antigas da sua biblioteca.

Lembre-se, o pom, depois de deployado, é imutável  - a URL ficará gravada para sempre e sejá quem esteja tentando utilizar essa versão vai ter muita dor de cabeça.





Digamos que você tem um projeto que tem como dependência (direta ou transitiva, mesma coisa nesse caso) uma biblioteca do jersey, que possui este pom.xml. No fim do arquivo você pode encontrar:


<repository>
<id>glassfish-repository</id>
<name>Repository for Glassfish</name>
<url>
http://maven.glassfish.org/content/groups/glassfish
</url>
</repository>
</repositories> 

E de repente, não mais que de repente, o repositório sai do ar. Assim, foi desligado, mudou de endereço, qualquer coisa assim. Anos se passaram, né?



Você inocentemente pensa que só precisa definir no seu projeto outro "repository" apontando pro novo endereço, né? Ledo engano!

Maven requer que todos os repositórios de todos os pom.xml que ele encontrar sejam válidos. Mesmo que todos os artefatos necessários estivessem disponíveis em outros repositórios válidos você simplesmente não consegue mais utilizar aquela versão do artefato. O build não falha por falta de artefato, falha por que um dos repositórios está dando "404 - not found".


Pior: o maven procurará as dependências SNAPSHOTs/LATESTs/RELEASEs em cada um dos repositórios definidos no seu settings.xml, nos seus poms, e em qualquer um dos poms incluídos transitivamente.  


Então, se não for pra usar no pom, o que você deve fazer?
  • Defina no settings.xml 
  • Crie um repositório no Nexus que agregue todos os proxies que você necessite, e aponte o seu settings.xml apenas para esse repositório

Se por acaso um repositório morrer, você pode corrigir o seu proxy (ou corrigir o settings.xml), e todas as versões antigas da sua biblioteca serão (mais) facilmente utilizáveis.




Soluções nesse caso de sumiço de repositório de uma biblioteca que você utilize:
  • Faça upgrade pra uma versão que não tenha um repositório inválido. Simplesmente faça.
  • Caso isso não seja possível, a única gambiarra é definir um mirror no settings.xml de todo mundo, apontando pra onde achar as dependências. Nojento de feio.

Ciclo de vida do maven: ou porque fazer "mvn verify deploy" é estúpido

Minha definição de maven é:

Maven serve para gerenciar dependências e executar plugins do maven

Ok, eu sei que é meio recursivo, mas sinceramente? O maven faz ~apenas~ isso. "Apenas".

Gerenciar dependências vocês entendem, né? Fazer download disso, calcular a versão a baixar, etc, etc. Super complexo de implementar, mas simples de entender.


Entenda um plugin do maven como um executável qualquer, que tenha qualquer objetivo. Um plugin tem um "nome" e a lista de "goals", comandos.
Então, quando vossa senhoria executa mvn dependency:tree, é uma simples invocação do goal "tree" do plugin "dependency". Mole?

Acontece que o maven tem os seus ciclos de vida. São apenas três: clean, default, site. Vou colar aqui as fases do "default", que é o que usamos mais:

validate
initialize
generate-sources
process-sources
generate-resources
process-resources
compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classes
test
prepare-package
package
pre-integration-test
integration-test
post-integration-test
verify
install
deploy

É uma sequência, isto é "mvn install" fará tudo o que "mvn verify" faz e mais alguma coisa. Assim como o "deploy" apenas ocorre após o "install"

 
Ciclo de vida é apenas uma maneira de simplificar e ordenar a chamada dos plugins.
Entenda que a cada fase, um ou mais plugins poderão ser chamados. Por padrão, o maven já faz a ligação de alguns plugins a determinadas fases (e vc não consegue desfazer essa ligação. Você pode adicionar plugins, nunca retirar). Dê uma olha em Lifecycle Bindings


Para adicionar plugins ao seu ciclo de vida não é difícil: existe uma seção chamada "plugins" dentro do seu pom.xml; na configuração do plugin, você pode dizer a que fase ele está ligado. Caso você não especifique, o plugin/goal já virá com uma fase padrão.


A saber: o ciclo de vida de "site" é utilizado pelo plugin de release.

domingo, 27 de outubro de 2013

Plugin de release: ruim com ele, pior sem ele

Das certezas da vida: você odiará o plugin de release. (Aqui para ler a documentação do bonito).

A teoria é linda e fofa. O goal release:prepare irá:
  1. Criar uma tag com o nome da versão
  2. Mudar todos os seus pom.xml pra versão que vc fará release
  3. Fazer um "mvn clean install" pra ver se os testes passam todos
  4. Incrementar o seus pom.xml pra nova versão SNAPSHOT
  5. Fazer commit&push dessas parada tudo 
Depois disso, vc pode executar release:perform:
  1. Fazer checkout daquela tag
  2. Fazer OUTRO "mvn clean install" (tipo por que não, né?)
  3. Fazer "deploy" dos seus binários todos (pro nexus ou qualquer lugar que vc configurou no seu "distributionManagement")
  4. Gerar javadoc, sources e fazer deploy também

Parece bem legal se você pensar que você terá a tag no seu SCM, e ela bate com o artefato que foi para seu maven remoto, etc. Uma coisa engenhosa e linda.


Para que funcione no seu projeto, a teoria diz que você apenas precisa definir adequadamente a tag "scm" no seu pom.xml.

Além disso, você obviamente precisa configurar para onde as coisas serão deployadas:


Simples, né? Vamos aos detalhes, porque sabemos que "o demônio mora nos detalhes".

  • Por padrão, o goal prepare irá pedir para que você confirme a versão nova, a versão a fazer release, o nome da tag. Invocar o maven em batch mode (-B) usará os valores default.
  • O release:perform irá criar uns arquivos temporários para que o release:perform seja executado. Isso é, você não pode fazer um prepare em uma máquina e o perform em outra. 
  • Rollback is a lie. Aceite. Se falhar por QUALQUER motivo, o release:rollback não vai te ajudar, vai te deixar em estágios intermediários que não dá nem pra corrigir e ir pra frente nem voltar pra trás. Váaaarias vezes vc tem que consertar tudo manualmente.
  • Você tem a opção de usar "https" ao invés de "ssh" no scm. Mas não faça. O plugin de release vai te pedir para colocar username/password a cada mínima mudança. Faça por ssh. 
  • Tenha certeza de já ter feito commit, push, pull de toda e qualquer alteração no seu repositório
  • Não podem ocorrer commits entre o começo do release e o fim. Isso, manda todo mundo parar de commitar. 
  • Os "mvn clean install" rodam em uma outra invocação do maven, que não recebe os mesmos argumentos que você passa na linha de comando. Isto é, aqueles "-Dalgumacoisa" que seu build precisa não serão recebidos. Como opção, passe-os dentro do "-Darguments" ou como variáveis de ambiente
  • Caso você deseje ardentemente pular todos os testes (por sua conta e risco), utilize "-Darguments='-DskipTests'", e nunca "-Darguments='-Dmaven.test.skip'". O último faria com que os jars de testes não fossem nem gerados, nem deployados.
  • Por padrão o perform irá fazer o deploy e deploy-site, além de habilitar o profile "release-profile". Isso é totalmente configurável no plugin, então sinta-se em casa.

Como a documentação é sua melhor amiga, vá lá e sinta-se à vontade. 
E claro, nada te impede de fazer release a partir do CI ;) Apenas garanta que o usuário tem permissão de escrita, que não é "shallow clone" (se for um checkout git), e pronto.

segunda-feira, 23 de setembro de 2013

O conto do artefato estável que foi "deployed" mais de uma vez

No mundo maven, existem dois "tipos" de repositórios: o local (~/.m2/repository por padrão) e os remotos (por exemplo, maven central). Verdade seja dita, basicamente qualquer servidor pode se tornar um repositório remoto, mas isso é meio tosco demais pro meu gosto.

Vamos ao jeito decente.

  • Se você tem um open source, você pode dar uma olhadinha em maven central
  • Se você está dentro de uma companhia, você pode googlar por "maven artifact repository manager". Por exemplo, essa comparação. Eu só tenho experiência com o Nexus, e provavelmente a versão open source vai atender bem suas necessidades. Mas tome vergonha nessa cara e bote um Repository Manager dentro da tua companhia, não faça gambiarras just because. (**)


Então digamos que você configurou o seu ambiente e/ou projeto para também olhar esse novo repository manager (no seu settings.xml ou pom.xml). Isso quer dizer que, na hora de procurar dependências faltantes, o maven irá olhar também esse servidor.


Um dia feliz no trabalho, e seu colega acabou de fazer release do artefato "com.mycompany.me:nice-artifact:4.5", e te avisa. Você, ávido pelas novas features, faz o upgrade no seu projeto.


<dependency>
    <groupId>com.mycompany.me</groupId>
    <artifactId>nice-artifact</artifactId>
-   <version>4.4</version>
+  <version>4.5</version>
</dependency>


Aparentemente tudo funciona, tudo lindo. Você faz commit, seus coleguinhas também fazem uns "git pull", a vida parece linda e normal. Até que alguma alma santa descobre um bug crítico na tal versão 4.5, severo a ponto de causar falhas de seguranças gravíssimas.

E alguém tem a brilhante idéia de modificar o troço e fazer o redeploy. (***)







Isto é, quem pegou a versão antiga do artefato, continuará usando a versão antiga. Quem ainda não pegou, pegará a nova. Pessoas diferentes usarão artefatos diferentes. Lembre-se também dos agentes de build.... alguns vão ter versão nova, alguns antiga, bugs surgindo sabe-se lá daonde, e uma versão 4.5 que significa nada.


Situação real: commons-io resolveu mover um jar de um groupId para outro. DEPOIS do release. O jar continuava o mesmo, mas obviamente o arquivo pom.xml mudava. Como eu tenho um plugin que olha informações no pom.xml, o desgraçado dava informações diferentes dependendo se a pessoa tinha feito o download antes de mudar ou depois. Pior ainda se você adicionar uma estrutura que possui cerca de 5 proxies espalhados pelo mundo.



Quer a dica? Desapegue de números. É uma versão, um número apenas. O plugin de release falha tantas vezes que o melhor mesmo é tratar isso como um número sem o menor apego. Aceite.
Queime quantos números forem necessários. Mas nunca sobrescreva.




** Vocês conhecem as regras. Se você não paga seus "tech debts", você vai à falência com os juros
*** É verdade que se pode configurar o Nexus para não aceitar redeploy, mas isso depende do seu tipo de build. Algumas limitações podem te impedir de configurá-lo desse jeito. 

domingo, 22 de setembro de 2013

SNAPSHOTs versions

Cada vez que vc faz "mvn install" numa versão que não é SNAPSHOT, essa é minha reação:



Gente, não. Não, não, não.


Uma versão estável, isso é, uma que não termina com "SNAPSHOT", é considerada imutável. IMUTÁVEL. Qualquer coisa que você esteja desenvolvendo obrigatoriamente tem que ser "SNAPSHOT".



O que isso significa?


Digamos que você está chamando o maven como de costume. Em qualquer projeto, mvn test.
O maven vai lá, procura todas as dependências. Se uma dependência não é SNAPSHOT, ele assume que, se já está no maven local repo (aquela pasta ~/.m2/repository), aquilo tá certo. Se você foi lesado de sobreescrever uma versão que NÃO É a correta, só deletando os arquivos pra consertar.

SNAPSHOT versions tem outro tratamento, mas fica pra outro post.


Opções:
  • Usualmente você não precisa rodar "mvn install". Um "mvn verify" pode te salvar muitas vezes
  • Se existir realmente motivo para recompilar uma versão já estável, use um outro maven local repo : "mvn -Dmaven.repo.local=$HOME/.my/other/repository install"
  • Pra fazer release, use o plugin de release. Ajuda com tag, com pom file, com deploy.
  • Ok, esse plugin de release é a besta do apocalypse em forma de plugin, você pode dar uma olhada no git-workflow plugin.

terça-feira, 17 de setembro de 2013

Mudança de planos

Eu tenho esse blog desde guaraná com rolha, e sinceramente, a idéia é boa mas eu nunca me policiei.

Mudei de vida, larguei das dorga, agora não mexo mais com essas paradas de apresentação.


Sou devops.  (#sóQueNão)
Em tempo: http://devopsreactions.tumblr.com/


Em tempo 2: sou ruiva, mas não tenho habilidade nem pra pintar a bonequinha no paint.

Em tempo 3: foda-se, o blog é meu, eu faço ele tão "girlie" quanto eu quero.