Variância em Java

Variância em sistemas de tipos de linguagens orientas a objectos é uma noção simples e com a qual nos deparamos todos os dias mas é complexa de explicar. Eu tenho normalmente dificuldade em explicar o que é a outras pessoas por isso decidi escrever este post e assim mando-lhes apenas o link :)

Variância neste contexto está directamente relacionada com herança. É relevante para compreender como é feito matching de parametros de métodos, resultados de retorno, tipos genéricos e outros casos.

Existem três tipos de variância: invariância, covariância e contravariância.

  • Covariância
  • Suponhamos o seguinte caso:

    public class X {
        Object getValue() { return null; }
    }
    
    public class Y extends X {
        String getValue() { return null; }
    }

    A covariância neste caso está no tipo de retorno. Significa que se a classe Y é mais específica que X (Y< X) então qualquer método de Y que faça override a um método de X tem de retornar um tipo igual ou mais específico. Neste caso, o tipo de retorno do método que faz override é String, que é mais específico que Object.
    Diz-se, pois, que os tipos de retornos em Java são covariantes (desde a versão 1.5).

  • Contravariância
  • Contravariância é efectivamente o inverso de covariância. Significa que se a classe Y é mais específica que X (Y<X) então qualquer método de Y que faça override a um método de X tem de retornar um tipo igual ou mais genérico.

    Em Java não há contravariância e overriding de métodos é sempre invariante … que passo a explicar de seguida. É no entanto possível ter contravariância usando wildcards de generics.

  • Invariância
  • Em Java overriding de métodos é invariante, ou seja, para se redefinir um método numa subclasse, os parâmetros têm de ser exactamente do mesmo tipo do seu ancestror.

    Este comportamento é muitas vezes descurado, veja-se o seguinte exemplo:

    public class A {
        boolean equals(A object) {
            //Fantastico, sempre igual
            return true;
        }
    }

    Como o overriding é invariante, não estamos na realidade a fazer override do método boolean equals(Object o) mas sim overload, adicionando um novo método com outra assinatura. O pior é que passa completamente despercebido.

    A solução desde Java 5 é adicionar a anotação @Override que vai permitir que o compilador detecte estes casos e informe que não estamos realmente a redifinir um método. Aliás, todos os IDEs decentes sugerem que se adicione esta anotação.

Uma nota sobre Generics

As noções de covariância e contravariância são importantes de ter presente quando definindo classes tipificadas com generics, especialmente quando se usam as wildcards para explicitamente definir relações entre tipos. Não estamos a definir realmente relações hierárquicas entre tipos, pois não há a relação de herança entre classes genéricas mas estamos a definir relações entre os tipos que parametrizam essa classe, se me consigo fazer entender.

Por exemplo:

public class Teste {
    void pseudoCovariante(List<? extends A> param) {}

    void pseudoContravariante(List<? super A> param) {}
}

Aqui definimos dois métodos para dar exemplos de como dotar classes tipificadas de noções de contravariância e covariância, já que se não usarmos wildcards temos parametros invariantes.

Espero ter conseguido explicar os conceitos básicos. Estas noções aparecem em diversos textos sobre linguagens de programação e é essencial compreender estas noções para se entender bem o sistema de tipos da linguagem Java.

JavaOne – Rescaldo

Passaram alguns dias desde o fim do JavaOne e ainda não tinha relatado o último dia nem feito um resumo geral do que foi o evento este ano.

O último dia do JavaOne é já um dia de descompressão. Há menos gente, as pessoas estão cansadas e, para dizer a verdade, as sessões não eram tão apelativas.
Na noite anterior veio o aviso urgente de um surto de virus – o Norovirus – no complexo do JavaOne com grande alarme. Resume-se a um vírus que se espalhou rapidamente por mais de 70 pessoas que trabalhavam no recinto e que atacava o estômago de forma violenta. No entanto, penso que não foi isso que fez com que pouca gente tivesse ido ao último dia e disseram-me que era normal.

No dia fui apenas a duas sessões:

  • Using Java Technology at the World’s Largest Web Site
  • Esta apresentação foi feita por duas pessoas da Yahoo! e pretendeu dar uma ideia sobre como e para quê eles usam java no que eles chamam o maior site da web.
    Tendo em conta que a Yahoo! não é propriamente uma empresa Java, percebeu-se que usam Java mais para a camada de middleware sendo que os serviços que residem por baixo são coisas em JNI feitas noutras linguagens ou outros serviços desenvolvidos noutras linguagens.
    Um dos grandes desafios que sentiram foi a nível de performance, escalabilidade e disponibilidade. Para ultrapassarem este problema, eles usam uma versão deles alterada do Tomcat que lhes permite colocar vários processos à escuta do mesmo porto paralelamente, garantindo o que eles denominam de load balancing aplicacional. Não entraram em grandes detalhes além de dizerem que tentam sempre utilizar tecnologias opensource e que sejam comummente aceite (Maven e Hibernate, por exemplo).

    No entanto, penso que transpareceu

    a ideia que Java é pequeno, bastante pequeno, no mundo Y!, em relação ao C/C++ e PHP.

  • GlassFish Project Web Services Stack “Metro”: Easy to Use, Robust, and High-Performance
  • Tinhas algumas espectativas para esta sessão mas saíram goradas. Foi apresentada pelo Jitendra Kotamraju (o homem JAX-WS) e o Marek Potociar, ambos funcionários da Sun.
    Como alguns funcionários da Sun fazem actualmente, tentaram evangelizar

    tentando vender o Netbeans: as demos eram feitas todas com wizards do netbeans e com comentários de é tão fácil e gera tudo – já todos passámos pelas demos em que é tudo fácil :)
    A apresentação em si foi bastante superficial no que toca ao Metro e focou-se em coisas bastante específicas do JAX-WS, nomeadamente no envio de attachments grandes. Gostei da forma como é possível abrir streams para enviar e ir gravando bytes sem ter de guardar tudo em memória. Quer isto dizer que não preciso de meter um attachment todo numa mensagem e enviá-lo, ou de o dividir: o cliente faz stream para o servidor que o vai guardando no destino, sem ocupar mais memória do que a de uns quantos chuncks que tem temporariamente.
    De resto, não sobrou muita coisa de interesse na apresentação, pois perderam tempo a mostrar como se criavam webservices jax-ws que além de não ser novo, não é propriamente complicado de perceber para os casos simples demonstrados.

De seguida baldei-me às sessões finais. Estava cansado e algumas cobriam coisas que já tinha visto noutros dias (processamento multicore e segurança em web 2.0) portanto foi o resto para descansar.

O que fica do JavaOne

Olhando para trás com alguns dias de distância, o JavaOne é um evento certamente a participar. Aprende-se, trocam-se ideias e conhecem-se pessoas. Uma viagem destas vale muito mais dinheiro do que uma qualquer formação e sai a um preço semelhante (<2500€ TUDO) por isso é algo em que as empresas devem pensar um pouco mais. Mas afinal, o que fica do JavaOne 2008?

  • JavaFX ainda longe
  • Como disse num post anterior, a Sun tentou vender novamente o JavaFX dedicando-lhe muito tempo na keynote inicial. Ficou demonstrado que ainda há muito trabalho a fazer e nos corredores a conversa era mesmo de descrença em relação ao futuro contra Flash/Flex/Air e Silverlight. O JavaFX terá de ser bastante bom para me desviar do Flex/Air para RIAs.

  • O mundo multi-core está cá
  • Imensas sessões acabaram falando da necessidade de tirar partido das máquinas multicore que por aí polulam. Enquanto antes uma máquina 32 cores era muita fruta, agora facilmente conseguem-se máquinas com 4 ou 8 vezes mais cores mudando apenas os tipos de processadores. Falou disto na palestra de Fortress, que tem primitivas tipo fork-join na base, falou-se em Scala que usa o modelo de Actors também para isto, falou-se – obrigatoriamente – na palestra do Brian Goetz e na de memória transaccional. E isto apenas nas que eu fui.
    É realmente importantíssimo pois agora o problema deixa de ser tentar dividir os ciclos de processador entre as nossas threads para antes dividir as nossas threads por vários cores e dar-lhes trabalho. Escreverei mais sobre o fork-join noutra altura pois é muito interessante.

  • Linguagens dinâmicas
  • JRuby, Groovy, Scala e Javascript tiveram espaço em diversas sessões. Falou-se muito especialmente de JRuby e Groovy, sendo que Groovy e Grails parecem ter deixado as pessoas mais maravilhados. Eu que sou um gajo statically typed e chato, gosto muito do Scala.

  • Networking
  • Quando falo de networking estou a falar de conhecer e trocar ideias com outros developers, pois lá não há a conversa de recrutamento nem nada disso. É fácil falar tanto com o zé ninguém como o mais conceituado membro da comunidade java. As diversas festas no fim de cada proporcionam esse tipo de contacto e os cartões de visita são absolutamente obrigatórios de levar.
    Algumas das conversas mais interessantes que tive foram mesmo nesses fins de noite.

  • JUG
  • A nível do JUG o JavaOne foi excelente tanto a nível de contactos como de ideias para melhorar a nossa comunidade. Tive relatos de JUGs muito diferentes e que funcionam muito bem – imaginem-se as diferenças entre um JUG Norueguês e um Brasileiro.
    Esta experiência servirá para introduzir ideias no nosso JUG e com sorte fazer “coisas bonitas” e ficam os contactos com especialmente com o pessoal dos JUGs do Brasil e Paris, tudo boa gente.

Resumindo, vale a pena. É cansativo e longe mas altamente recompensador tanto para quem vai como para a empresa que patrocina. Por isso tentem convencer a vossa empresa, bem explicado podem ver a importância de um evento deste.

Properties na linguagem java

Quando brinquei com C#, uma das coisas pelas quais fiquei apaixonado foi a implementação deles de properties. Enquanto em java temos a especificação dos JavaBeans e os nossos getters e setters de atributos são métodos que têm de corresponder a uma determinada nomenclatura, em C# essa definição é ao nível da sintaxe da linguagem.

O uso de getters e setters em java não deixam de me parecer como uma solução de recurso que passou a standard. Se se implementarem properties agora, teríamos sempre de manter o suporte para aquela horrível nomenclatura a que todos nos habituámos a não odiar.

Além disso é já hoje em dia uma questão cultural mudar uma prática tão enraízada. Penso mesmo que mais são os opositores à ideia – lembro-me de uns whiteboards no JavaPolis neste ano com propostas e votações

sobre as futuras alterações à linguagem java e que deixo a imagem em baixo. Também há uma descrição mais promenorizada na página do Javapolis.

langchange-dscf3611.JPG

Eu pessoalmente,

gostava bastante de poder usar propriedades em Java.

JavaOne 2008: Vou estar lá :)

Nestas últimas 2 semanas, em que não tenho escrito nada aqui no Zona J, tenho estado a preparar a minha ida ao JavaOne pela primeira vez.

O JavaOne ocorre em São Francisco de 6 a 9 de Maio e é a maior conferência de developers do mundo. Serão mais de 320 sessões técnicas em 4 dias (para quem é demasiado preguiçoso para fazer as contas, isto dá 80 sessões por dia!) e se algo pode ser dito para demonstrar a força da indústria e comunidade à volta da tecnologia Java, esta é a maior prova.

Eu sempre quis ir ao JavaOne pois todas as pessoas que lá estiveram (entre eles o Ricardo Antunes aqui do Zona J) o descreveram como uma experiência obrigatória. A oportunidade surgiu com um programa da Sun EUA de Top Bloggers em que acabei por ser escolhido e foi-me enviado um convite de entrada na conferência como blogger/press – quer isto dizer que vou poder fazer de jornalista e cobrir o evento mas, acima de tudo, devo ter comida de graça. Feito o convite, tinha mesmo de ir e a empresa onde eu trabalho, a Karma Consulting, deu-me a ajuda que eu precisava para a viagem – obrigado chefe!.

Quando custa ir ao JavaOne

A ida a uma conferência deste género tem custos elevados. Mesmo com o dólar a valer quase o mesmo que o Yen, a ida à conferência com origem em Lisboa, tem os seguintes gastos:

  • Entrada na conferência – $1495/€950
  • A entrada ao preço early bid é de $1595 mas o PTJUG (e todos os outros JUGs) tem um desconto de $100 se usarem um código específico. Esse código pode ser encontrado na mailing list do PTJUG, para quem estiver interessado.

  • Viagem avião – aprox. €1000
  • O preço da viagem de avião pode variar muito consoante a disponibilidade e os voos viagra mais baratos são por vezes difíceis, mas com alguma antecedência conseguem-se voos a €800. Além disso a viagem é muito longa, especialmente nas rates mais baixas em que se fazem 2 escalas e a duração de voo ultrapassa as 23 horas!

  • Estadia – aprox. 500€
  • A conferência tem um conjunto de hotéis com os quais combina as rates e um hotel médio custa cerca de $150/95€ por noite. Se contarmos 5 noites, arredondamos para 500€

  • Gastos extra – ??
  • Com tanta sessão técnica para ver, não deverá haver muito tempo para gastar dinheiro. Será seguro pensar em algo tipo €500.

Resumindo, €3000 é uma conta redonda e próxima do que pode custar ir ao JavaOne. Na minha opinião, para os benefícios

que traz é bem mais interessante para uma empresa promover a ida dos seus funcionários a uma conferência destas do que pagar cursos de certificação para figurarem no CV por preços semelhantes.

Que sessões vou ver no JavaOne

O site oficial do evento oferece um sistema de escolha das sessões técnicas. Dentro destas há as sessões técnicas propriamente ditas, mais conceituadas e formais; e os BOFs, ou Birds of Feather, que são sessões mais pequenas e informais.
Com tanta sessão interessante demora-se mesmo muito tempo a escolher as sessões que queremos ver, mas posso destacar as seguintes sessões que planeio ver:

  • Fortress: A Next-Generation Programming Language Brought to You by Sun Labs
  • Fortress é uma linguagem saída dos Sun Research Labs que tem coisas como paralelismo implícito (o código escrito é paralelizado por omissão, sempre que possível), notação matemática na linguagem, transaccionalidade e outras coisas interessantes.

  • Defective Java™ Code: Turning WTF Code into a Learning Experience
  • Esta sessão via ser dada pelo William Pugh, criador do FindBugs e será uma aproximação prática com projectos reais, como seja o OpenJDK.

  • JUG Community BOF: JUG Leaders from Around the World Interact with Sun
  • JUG Leaders e representantes da Sun reunem-se para falar sobre o funcionamento das comunidades de JUG e a sua relação com a Sun.

  • Comet: The Rise of Highly Interactive Web Sites
  • Apresentada pelo Joe Walker, do DWR.

  • Top 10 Patterns for Scaling Out Java™ Technology-Based Applications
  • Sessões dada pelo Cameron Purdy, ex-CEO da Tangosol, agora na Oracle e à frente da área de desenvolvimento. É certamente a pessoa indicada para falar de temas como escalabilidade e computação em grelha. Deverá falar bastante de Oracle Coherence.

  • Programming with Functional Objects in Scala
  • Uma das sessões que tenho mais expectativa. Sou um fã da linguagem Scala, embora ainda não possa ter usado a linguagem para umas brincadeiras práticas. O senhor Martin Odersky em pessoa vai apresentar a sessão.

  • Meet the Java™ Posse
  • Sou ouvinte regular do podcast The Java Posse e este BOF será certamente divertido. Vai ser uma oportunidade de ligar as caras aos nomes e vozes.

Tenho muitas mais sessões no meu horário e tenho a certeza que mesmo que não consiga ir a todas, vou perder algum peso a correr entre elas.

Para quem ainda quiser ir ao JavaOne este ano, não se esqueça que o preço do Early Bid acaba a 7 de Abril e que podem obter o tal desconto de $100.
Se alguém estiver a ler e for ao JavaOne diga alguma coisa nos comentários, terei todo o gosto em combinar alguma coisa visto que vou sozinho e sou uma pessoa muito anti-social.

Google Collections Library

Não sei como só vi isto agora mas já está disponível há algum tempo, embora ainda em 0.5 (Alpha).
Trata-se uma biblioteca desenvolvida internamente por pessoal do Google e disponibilizada ao público em geral com uma licença opensource. Pretende ser

uma extensão às Java collections, e as colecções estendem os tipos base das colecções.

Novas Collections

São definidos, os seguintes novos tipos de colecções:

  • BiMap
  • Esta interface estende Map e permite ter um Map bidireccional, ou seja, em que é possível aceder por chave e/ou por valor. São fornecidas três implementações: HashBiMap, EnumBiMap e HashEnumBiMap.
    O HashBiMap contém dois HashMaps e permite a utilização de chaves e valores null. O EnumBiMap utiliza dois EnumMaps na sua implementação mas não permite chaves e valores null. O HashEnumBiMap é um misto, sendo que utiliza um EnumMap para mapear chaves para valores e um HashMap para mapear valores para chaves.

  • Multimap
  • É uma Map que pode ter vários valores para cada chave, ou seja, pode-se fazer algo como

    myMultimap.put(chavexpto,valorA);
    

    As vezes que quisermos, com a mesma chave. Existem dois interfaces principais que extendem Multimap: ListMultimap e SetMultimap.
    O ListMultimap guarda internamente os valores para uma chave numa lista ordenada, preservando assim ordem de inserção. São fornecidas as implementações ArrayListMultimap e LinkedListMultimap.
    O SetMultimap utiliza um Set para guardar os valores de cada chave e por isso não permite pares (chave,valor) repetido. São fornecidas as implementações HashMultimap, LinkedHashMultimap e TreeMultimap. Os nomes penso que são intuitivos :)

  • Multiset
  • É simplesmente um Set que permite duplicados, comummente chamado de Bag.
    Cada elemento tem um número de ocorrências, sendo que a noção de vários elementos com o mesmo valor não tem lógica, mas sim um elemento com X ocorrências. O número de ocorrências de um elemento é alterado quando o mesmo valor é inserido várias vezes e a igualidade entre valores é dependente da classe implementadora do Multiset (e.g. um HashMultiset poderá simplesmente comparar hashcodes, outro poderá ter uma aproximação diferente). Para oferecer esta noção de ocorrência, é fornecido o método

    int count(Object);
    

    São fornecidas as implementações EnumMultiset, HashMultiset, LinkedHashMultiset e TreeMultiset.

Além destas, existem mais classes de colecções derivadas, que estendem algumas das que aqui falei.

Classes Auxiliares

São fornecidas inúmeras classes auxiliares, mais do que as que consigo enumerar aqui e a maioria ainda nem olhei para elas.
Posso destacar alguns helpers, como seja por exemplo os Builders para criar colecções imutáveis de Multimap e BiMap ou um muito útil AbstractIterator, para facilitar a implementação de Iterators.
São fornecidas também Forward Collections, que são colecções que delegam o processamento dos seus métodos nos métodos de uma classe filha. Isto é útil porque a maioria das classes fornecidas pelo google collections library são

final e esta é a forma de adicionar comportamento personalizado. O pattern usado nestas forward collections é o decorator.

Base Google Goodies :)

Além das colecções e classes auxiliares relacionadas, são incluídas e utilizadas classes base e utilitárias google. São coisas simples e algumas delas bem pensadas e que podem ser utilizadas no dia-a-dia. Destaco a classe Preconditions: um conjunto de métodos estáticos para serem usados no início de métodos, para verificar pré-condições de argumentos e verificações de estado interno. Existem soluções de contratos mais completas obviamente mas como solução leve e prática é bastante usável.

Por fim, o mais importante, vão ao site do Google Collections Library, saquem o snapshot e vejam por vocês próprios. Poderá vir a ser uma boa adição aos nossos projectos.

Open Perspectives

Realiza-se no dia 17 de Outubro – sim é já depois de amanhã, quarta-feira – o Open Perspectives – “Views on Enterprise Software Development”.
Trata-se da primeira conferência organizada pela Lo

gical Software, será focada em metodologias ágeis e ferramentas próximas do mundo java. Terá a duração de 1 dia.
As Sessões são as seguintes:

  • Moving to Scrum
  • Orientação a Serviços
  • Desenvolvimento Web com Tapestry
  • Groovy up your Code

É de louvar ver empresas com iniciativas para eventos deste tipo com vista à troca de ideias e experiências. Penso que todos poderão ganhar algo se derem uma saltada pelo Hotal Príncipe Lisboa na quarta-feira, mesmo tão em cima do acontecimento.

Página do evento

Java: o futuro Cobol?

Antes de mais gostaria de pedir desculpa de falar sobre Cobol aqui, poderá trazer más memórias de alguns que em tempos passaram meses em caves escuras a programar na dita linguagem.
No início da minha carreira profissional – que não foi assim à tant

o tempo, embora possa referir sempre que foi “no século passado” – uma das poucas certezas que tinha era que não queria ir programar Cobol para uma cave de um banco como um amigo meu tinha estado uns meses ali para os lados da Av. da República. Sabia que queria programar, mas como a maioria dos entusiastas por tecnologia, queria trabalhar com paradigmas recentes ou pelo menos actuais, como seja linguagens orientadas a objectos. Depois, entrei no mundo do Java.

Como tecnologia, o Java é o principal player a penetrar em áreas anteriormente ocupadas pelo cobol (nos bancos, seguradoras, etc.), aplicações java substituem sistemas legacy e implantam-se no negócio das empresas. Temos montes de pequenas aplicações, temos EAIs para integrar aquilo tudo, temos, na realidade, java por todo o lado e tão cedo não deixará de estar presente nestas instituições. É a linguagem mais usada e com programadores a nível mundial na actualidade e ainda vai demorar algum tempo a ser ultrapassada.

Dado isto, propõe-se como exercício ao leitor que imagine a linguagem e a vm java daqui a 5, 10 e 20 anos. Não falamos das mudanças da próxima versão 7 do java, falamos a longo prazo. Chegaremos a um ponto em que olharemos para trás e pensamos na linguagem java como actualmente pensamos em cobol, um sistema legacy?
Põe-se a questão de qual será o caminho a seguir pelo java e, a meu ver, o sucesso apenas será atingido se analisarmos o termo java enquanto plataforma e não focando na linguagem. As linguagens de programação evoluem de acordo com paradigmas. Agora assistimos a um ressurgir da programação funcional em força com o ruby, erlang, scala e outras (haskell, scheme, ocaml, …): paradigmas já antigos mas agora contextualizados para o poder computacional dos tempos modernos.
Se os paradigmas evoluem com o tempo, tem toda a lógica olhar para a tecnologia java como uma plataforma que venha a suportar multiplas linguagens. A concepção do .net veio provar um pouco essa vantagem e nestes últimos 2 anos assistiu-se ao aparecimento de inúmeras linguagens para a Java VM como seja o jruby, groovy, jython, scala etc.

No fundo, não acredito que cheguemos sequer daqui a 5 anos a usar a linguagens java de forma tão monolítica como actualmente. Teremos uma

escolha maior de linguagens, a vm suportará linguagens dinâmicas de forma mais eficiente – esse trabalho está actualmente em curso – e nós, programadores, teremos de ser muito mais language agnostic do que muitas vezes somos. Se podemos desenvolver em várias linguagens para depois compilar para o mesmo bytecode, vamos usar a que melhor se adapta às nossas necessidades e também aos nossos gostos.

Enfim, confusões tecno-filosóficas de quem anda a brincar com BPM e não tem o direito de programar nada excepto nos tempos livres. Agradecem-se opiniões sobre o tema!

Liferay Portal 4.3.1 – Instalação do ambiente de desenvolvimento no eclipse 3.3 (Europa)

O Liferay Portal é uma solução empresarial de portal, open-source, desenvolvida em Java. Precisei recentemente de instalar o ambiente de desenvolvimento. A documentação disponível refere-se à v

ersão 4.2, está desactualizada e por isso contem bastantes incorrecções. Como o processo não é lá muito intuitivo resolvi fazer uma lista dos passos necessários para concluir a instalação. Aqui fica:

1 – Instalar o Liferay Portal

  • Comecem por fazer o download de um dos bundles do Liferay disponíveis no endereço http://www.liferay.com/web/guest/downloads. Eu optei pela versão recomendada, ou seja, com o Tomcat.
  • Criem uma pasta no vosso filesystem para servir como base da instalação – $LIFERAY_HOME. Dêem-lhe um nome sugestivo como por exemplo ‘liferay-portal’.
  • Dentro desta pasta, criem mais duas pastas, uma para conter a instalação do bundle do Liferay e outra para servir como workspace do eclipse (ex: $LIFERAY_HOME/tomcat e $LIFERAY_HOME/workspace).
  • Descompactem o conteúdo do ficheiro do bundle para a pasta $LIFERAY_HOME/tomcat.

2 – Testar a instalação

  • Executem o ficheiro $LIFERAY_HOME/tomcat/bin/startup.bat (ou startup.sh).
  • Abram um browser e apontem para o endereço http://localhost:8080/. Se tudo estiver bem devem conseguir ver a página inicial do liferay-portal.
  • Testar o login com as seguintes credenciais: [user]: test@liferay.com [pass]: test

3 – Importar o projecto para o eclipse a partir do repositório SVN

  • Abram o eclipse.
  • Criem um novo workspace na pasta $LIFERAY_HOME/workspace$WORKSPACE File > Switch Workspace >
    My over including one canadian pharmacy online you negligible again female viagra not that which daughter panic. So viagra Work stated better buy viagra Philippines I every little well – cialis online with meant apparently beautiful, always viagra online canada I those silk http://www.edtabsonline24h.com/ applied Ingredient! Because order cialis online face would. Some it just canadian pharmacy paypal appear company. Amazing ed drugs lift African dermatologist non-chemically cheap generic viagra heavy sensitivities, tried, buy generic viagra online can Very make me It…

    Other (indiquem a pasta $WORKSPACE e confirmem).

  • Importem o projecto a partir do SVN : File > Import > SVN > Projects from SVN.
    • Como URL indiquem o endereço https://lportal.svn.sourceforge.net/svnroot/lportal.
    • Seleccionem o projecto ‘portal‘ e dentro deste o ramo ‘trunk‘.
    • Seleccionem a opção ‘Check out as a project with the name specified:‘ e indiquem como nome do projecto ‘liferay-portal‘.
    • Deixem a opção ‘Checkout recursively‘ seleccionada.
    • Aproveitem agora para fazer uma pausa enquanto o eclipse faz o checkout do projecto. No final deverá aparecer o projecto ‘portal‘ no Project Explorer do eclipse.

    Nota: Se tiverem problemas no checkout voltem a repetir os passos anteriores mas desta vez desseleccionem a recursividade (Checkout recursively). O checkout termina rapidamente. Depois usem a opção team syncronize/update para obterem o projecto completo. Isto permite ter mais controlo sobre a operação pois, neste caso, é possível interromper o processo a qualquer altura e retomar posteriormente desde o ponto onde ficou.

  • Fechem o eclipse.

4 – Gerar e configurar o ambiente de desenvolvimento

Antes de dar inicio a este passo devem verificar se têm o ant 1.7.0 instalado. O build não funciona com versões anteriores. O Liferay usa o Jikes como compilador default. Se o pretendem usar e ainda não o têm instalado, agora é a altura ideal para o fazerem ;-). No meu caso, a natural preguiça levou-me a optar pelo habitual javac.

  • Abram uma consola de linha de comando na pasta $WORKSPACE/portal.
  • Criem o ficheiro build.$USER.properties, onde $USER deve ser substituido pelo vosso username na máquina ou, alternativamente, o nome da própria máquina, com o seguinte conteúdo: lp.ext.dir=$WORKSPACE/ext lp.eclipse.project.name=liferay-ext javac.fork=true javac.memoryMaximumSize=512m javac.compiler=modern (ignorem esta se estiverem a usar o jikes e não se esqueçam de substituir $WORKSPACE pelo path correspondente).
  • Executem o comando: ant clean start build-ext
  • Aproveitem para fazer mais uma pausa ;-) . Após a conclusão do build, deve existir uma pasta ext no vosso workspace.
  • Nesta pasta ($WORKSPACE/ext) criem o ficheiro app.server.$USER.properties onde, mais uma vez, $USER deve ser substituido pelo vosso username na máquina ou, alternativamente, o nome da própria máquina, e com o seguinte conteúdo : app.server.parent.dir= $LIFERAY_HOME app.server.tomcat.dir=${app.server.parent.dir}/tomcat (se estiverem a instalar um bundle diferente devem consultar os nomes das properties no ficheiro app.server.properties).
  • Caso não estejam a usar o jikes como compilador devem ainda criar o ficheiro build.$USER.properties, com o conteúdo: javac.compiler=modern javac.fork=true javac.memoryMaximumSize=256m
  • Ainda na mesma pasta ($WORKSPACE/ext), executem o comando: ant deploy.
  • Mais uma pausa (esta mais pequena).

5 – Importar o ambiente de desenvolvimento para o eclipse

  • Voltem a abrir o eclipse.
  • Importem o projecto ext (File > Import > Other > Existing Folder As New Project). Seleccionem a pasta $LIDERAY_HOME/ext.
  • Devem ter agora dois projectos no vosso workspaceportal e ext.
  • Seleccionem o projecto ext e acedam às suas properties.
  • Seleccionem a tabbuilders‘.
    • criem um novo builder (botão new).
    • Seleccionem o Ant Builder.
    • Nas propriedades do builder indiquem como buildfile o ficheiro build.xml que se encontra na pasta raiz do projecto ext ($WORKSPACE/ext).
    • De volta à tabbuilder‘ desseleccionem o ‘Java Builder‘. O eclipse pede uma confirmação: aceitem!
  • Se tiverem a opção de ‘auto-build‘ do eclipse activada, o eclipse deve dar inicio à compilação do projecto e… mais uma pausa.

6 – Configurar o ambiente de execução

  • Acedam novamente às properties do projecto ext.
  • Seleccionem a tabRun/Debug Settings‘.
  • No quadro ‘Create, manage and run configurations‘ seleccionem a opção ‘Run on Server‘ e depois o iconnew‘.
  • Seleccionem a configuração ‘tomcat‘ (ou outra, dependendo do bundle que estão a instalar).
  • Nas propriedades da configuração seleccionem a tab Arguments.
    • Substituam o valor dos argumentos -Djava.endorsed.dirs=${workspace_loc:ext/servers/tomcat/common/endorsed} -Dcatalina.base=${workspace_loc:ext/servers/tomcat} -Dcatalina.home=${workspace_loc:ext/servers/tomcat} -Djava.io.tmpdir=${workspace_loc:ext/servers/tomcat/temp} por -Djava.endorsed.dirs=${workspace_loc}/../tomcat/common/endorsed -Dcatalina.base=${workspace_loc}/../tomcat -Dcatalina.home=${workspace_loc}/../tomcat -Djava.io.tmpdir=${workspace_loc}/../tomcat/temp
    • No ‘Working Directory‘ indiquem o path para o directorio ‘bin’ do tomcat ($LIFERAY_HOME/tomcat/bin).
  • Ainda nas propriedades da configuração, seleccionem a tab Classpath
    • Removam a entrada que está marcada como erro (tools.jar).
    • Adicionem o bootstrap.jar do tomcat/bin como jar externo e removam a entrada existente para o mesmo ficheiro.
  • Confirmem as alterações.
  • Executem o projecto (Run). Devem ver o output do tomcat a ser dirigido para a consola do eclipse.

Confirmem que tudo está a funcionar seguindo os passos indicados no ponto 2. É claro que não precisam de executar o tomcat, o eclipse já tratou disso. O próximo passo será configurar a base de dados, mas isso ficará para um outro post ;-)