FeaturesPluginsDocs & SupportCommunityPartners

>> Mais documentação do Visual Web Pack

Usando componentes de vinculação de dados para acessar um banco de dados

Dezembro de 2006 [Número da revisão: V1-2]    

Neste tutorial, você usa o ambiente de desenvolvimento integrado (IDE) do NetBeans Visual Web Pack 5.5 para criar e implantar um aplicativo da Web que exiba dados mestre-detalhe a partir de um banco de dados incorporado ao IDE. No aplicativo, você seleciona uma pessoa na lista suspensa e ele exibe uma tabela que mostra todas as viagens registradas desta pessoa.

Conteúdo

Criando uma página que inclua um componente Lista suspensa
Conectando componente a um banco de dados
Adicionando um componente Tabela
Modificando a consulta SQL
Controlando as linhas exibidas
Fazendo mais
  O conteúdo desta página se aplica ao Netbeans Visual Web Pack 5.5
 

Antes de usar este tutorial, você deve ter o NetBeans 5.5 IDE e o Visual Web Pack 5.5 instalados no sistema. Familiarize-se com as partes básicas do IDE e leia Guia de introdução ao NetBeans Visual Web Pack 5.5 para uma introdução ao ambiente de desenvolvimento do Visual Web Pack.

Este tutorial funciona com as tecnologias e os recursos seguintes

Componentes JavaServer Faces/
Plataforma Java EE
funciona com 1.2 com Java EE 5*
funciona com 1.1 com J2EE 1.4
Banco de dados Viagem necessárioNecessário
Biblioteca de componentes BluePrints Ajax não é necessárioNão é necessário

* Na data da publicação deste tutorial, somente o servidor de aplicativos Sun Java System oferecia suporte ao Java EE 5.

Este tutorial foi adaptado para ser usado com o Servidor de aplicativos Sun Java System PE 9.0, versão atualizada 1, e o Tomcat 5.5.17. Se você estiver usando um servidor diferente, consulte as Notas de versão e as Perguntas freqüentes para obter informações sobre problemas conhecidos e soluções sugeridas. Para obter informações detalhadas sobre os servidores suportados e a plataforma Java EE, consulte as Notas de versão.

Criando uma página que inclua um componente Lista suspensa

Neste tutorial, você constrói um aplicativo Central de viagens como mostrado na figura do aplicativo implantado abaixo.

Figura 1: Aplicativo da Web Central de viagens
Figura 1: Aplicativo da Web Central de viagens

Comece criando a home page e adicionando um componente Lista suspensa à página.
  1. Crie um novo projeto e nomeie-o ComponentesDeVinculaçãoDeDados. O IDE cria uma página de início padrão denominada Page1 e exibe a página no Visual Designer.
  2. Se o nó Básico da janela Paleta não estiver expandido, expanda-o.
  3. Arraste um componente Rótulo para o lado esquerdo da página, digite Selecionar nome: e pressione Enter.
  4. Arraste um componente Lista suspensa para o lado direito do componente Rótulo.
  5. Na janela Propriedades, altere o id para personIdDD.
  6. Use Ctrl-Shift-arrastar do componente Lista suspensa para o componente Rótulo para criar uma relação entre os dois componentes.

    A propriedade for do componente Rótulo está definida agora como personIdDD.
  7. Arraste um componente Grupo de mensagens da janela Paleta para um lugar fora da página, como o canto superior direito desta.

    Este componente é útil para diagnosticar erros de programação. Você pode fazer com que mensagens de diagnósticos sejam exibidas neste componente chamando o método info(String), error(String), warn(String) ou fatal(String). O componente Grupo de mensagens exibe o valor do argumento String. Além disso, as mensagens sobre erros de tempo de execução, erros de validação e erros de conversão aparecem por padrão neste componente.

Conectando componente a um banco de dados

A janela Tempo de execução, que aparece do lado esquerdo da área de trabalho do IDE, inclui um nó Bancos de dados. O nó Bancos de dados mostra todos os drivers e conexões do banco de dados que foram adicionados ao IDE.

O NetBeans Visual Web Pack 5.5 vem com um banco de dados Viagem de amostra que se encontra no nó Bancos de dados.

Ao vincular um banco de dados a um componente, você cria duas camadas entre o componente e a tabela de banco de dados: a camada RowSet e a camada Provedor de dados. A camada RowSet faz a conexão ao banco de dados, executa as consultas e gerencia o conjunto de resultados. A camada Provedor de dados fornece uma interface comum para acessar muitos tipos de dados, de conjuntos de linhas a objetos Array e objetos Enterprise JavaBeans.

Geralmente, a única vez que você trabalha com o objeto RowSet é quando precisa definir os parâmetros de consulta. Na maioria dos casos, você usa o Provedor de dados para acessar e manipular os dados. Você pode fazer declinar a sua curva de aprendizagem usando a API do provedor de dados, pois as mesmas APIs servem independentemente do tipo de dados que estão sendo empacotados (isto é, independentemente de qual implementação de provedor de dados você está usando).

Nesta seção do tutorial, você usa a tabela PESSOA do banco de dados Viagem para fornecer as opções do componente Lista suspensa.
  1. Na janela Tempo de execução, expanda o nó Bancos de dados e verifique se o banco de dados VIAGEM está conectado.

    Se o nó jdbc do emblema do banco de dados VIAGEM estiver partido e você não puder expandir o nó, o IDE não está conectado ao banco de dados. Para conectar ao banco de dados VIAGEM, clique com o botão direito do mouse no nó jdbc de VIAGEM e escolha Conectar no menu pop-up. Se a caixa de diálogo Conectar for exibida, digite viagem para o Usuário e para a Senha, selecione Lembrar senha durante esta sessão e clique em OK. Se você não vir um nó jdbc no banco de dados VIAGEM, consulte Instruções de instalação do NetBeans Visual Web Pack 5.5 para obter informações sobre como disponibilizar o banco de dados para o IDE.
  2. Expanda o nó Viagem > Tabelas.

    Em Tabelas, você vê os nós de cada tabela no banco de dados, como ALUGUELDECARRO e VÔO. A figura abaixo mostra a janela Tempo de execução com o nó Tabelas expandido.

    Figura 2: Janela Servidores
    Figura 2: Janela Tempo de execução
  3. Arraste PESSOA da janela Tempo de execução e solte-o na Lista suspensa.

    O texto abc aparece no componente Lista suspensa. O texto abc indica que o campo de exibição está vinculado a um objeto String, que, neste caso, é uma coluna de banco de dados SQL do tipo varchar. Além disso, o IDE adiciona um componente personDataProvider não visual na tabela do banco de dados. O componente personDataProvider é exibido na janela Esboço. O IDE adiciona também uma propriedade personRowSet ao SessionBean1.
  4. Clique com o botão direito do mouse em Lista suspensa e escolha Vincular aos dados no menu pop-up. A caixa de diálogo Vincular aos dados é exibida, como mostrado na figura abaixo.

    Figura 3: Vinculando dados à lista suspensa
    Figura 3: Vinculando dados à lista suspensa
     
    Ao vincular dados a um componente Lista suspensa, você deve especificar o que será exibido na lista (o Campo de exibição) e que valores serão usados no programa subjacente (o Campo de valor). Normalmente, opta-se por exibir valores significativos da tabela de banco de dados, como o nome da pessoa, mas você quer usar um identificador exclusivo no programa subjacente, como o ID da pessoa. Com este aplicativo, no entanto, você opta por vincular os campos Valor e Exibição à mesma coluna de banco de dados, a coluna PERSON.NAME, conforme descrito nas duas etapas seguintes.
  5. Na caixa de diálogo Vincular aos dados, selecione PERSON.PERSONID na lista Campo de valor para fazer com que o método getSelected do componente retorne PERSON.PERSONID para a seleção atual.
  6. Selecione PERSON.NAME na lista Campo de exibição para fazer com que o navegador preencha a lista suspensa com os valores da coluna de banco de dados PERSON.NAME.
  7. Clique em OK.
  8. Clique em Executar > Executar projeto principal, na barra de ferramentas principal.

    O IDE salva todas as alterações e, em seguida, constrói, implanta e executa o aplicativo da Web. Primeiramente, a janela Saída é exibida na parte inferior do IDE. O IDE escreve as informações de preparação para a compilação e implantação desta janela. (Assim, se houver qualquer tipo de problema com a construção, verifique primeiro a janela Saída.) Depois, uma caixa de diálogo exibe o status da implantação. Depois de terminada a implantação, o IDE abre o navegador da Web do aplicativo. Quando o navegador renderiza a página, ele preenche a lista suspensa com os dados da coluna NAME da tabela PERSON.

Adicionando um componente Tabela

A seguir, você adiciona um componente Tabela ao seu aplicativo e conecta o componente a um banco de dados de tabela.
  1. Na Paleta, arraste um componente Tabela e coloque-o abaixo do componente Lista suspensa.
  2. Na janela Tempo de execução, expanda o nó Viagem > Tabelas.
  3. Arraste TRIP da janela Tempo de execução e solte-o na barra de título do componente Tabela.

    Observação: Se soltar o banco de dados TRIP em outra parte do componente Tabela, a caixa de diálogo Escolher destino é exibida. Na caixa de diálogo Escolher destino, selecione table1 e clique em OK.
  4. Clique com o botão direito do mouse no componente Tabela e selecione Layout da tabela.

    A lista Selecionado na caixa Layout da tabela mostra todas as colunas da tabela. Os itens da lista Selecionado são usados para especificar que colunas devem aparecer no componente Tabela.
  5. Use Ctrl-clique para selecionar todas as entradas na lista Selecionado, com exceção de TRIP.DEPDATE, TRIP.DEPCITY e TRIP.DESTCITY.
  6. Clique no botão <.

    As entradas selecionadas são deslocadas para a lista Disponível e as três entradas seguintes permanecem na lista Selecionado, como mostrado na figura abaixo:

    • TRIP.DEPDATE
    • TRIP.DEPCITY
    • TRIP.DESTCITY
    Figura 4: Caixa de diálogo Layout da tabela
    Figura 4: Caixa de diálogo Layout da tabela
  7. Clique em OK.

    O Visual Designer exibe agora três colunas no componente Tabela, como mostrado na figura abaixo.

    Figura 5: Exibição da coluna da tabela
    Figura 5: Exibição da coluna da tabela

Modificando a consulta SQL

A seguir, você modifica a consulta SQL no objeto tripRowSet para que a consulta também retorne dados da tabela TRIPTYPE. Você modifica também o componente Tabela para que exiba a descrição do tipo de viagem.
  1. Na janela Esboço, expanda o nó SessionBean1 se ainda não estiver expandido.

    Figura 6: A seção SessionBean1 na janela Esboço
    Figura 6: A seção SessionBean1 na janela Esboço
  2. Na seção SessionBean1 da janela Esboço, clique com o botão direito do mouse no nó tripRowSet e escolha Editar instrução SQL.

    O Editor de consultas aparece na área de edição, com uma guia tripRowSet.

    Dica: Se a janela Esboço for exibida, feche-a para que você tenha mais espaço para trabalhar com o Editor de consultas.
  3. Arraste o nó Viagem > Tabelas > TRIPTYPE da janela Tempo de execução e solte-o na exibição Design, como mostrado na Figura 7.

    Outro diagrama de tabela é exibido com um vínculo entre os dois diagramas da tabela. Este vínculo representa uma junção. Note como o IDE modificou a instrução de seleção no painel Código-fonte.
  4. Desmarque a caixa de seleção de TRIPTYPEID na tabela TRIPTYPE.

    Esta ação remove a coluna do conjunto de resultados e da consulta SQL que está no painel Código-fonte, como mostrado na figura abaixo.

    Figura 7: Editor de consultas
    Figura 7: Editor de consultas
  5. Deixe o Editor de consultas aberto.
  6. Clique na guia Page1 na área de edição.
  7. No Visual Designer, clique com o botão direito do mouse no componente Tabela e escolha Layout da tabela.

    A caixa de diálogo Layout da tabela é exibida. Devido à alteração realizada na consulta SQL de tripRowSet, há mais colunas do que é possível exibir.
  8. Adicione a coluna TRIPTYPE.DESCRIPTION à lista Selecionado.
  9. Clique em OK.

    Uma quarta coluna aparece no componente Tabela.

Controlando as linhas exibidas

No momento em que você adicionou um Provedor de dados na tabela TRIP, o IDE criou um objeto RowSet com uma consulta SQL que retornasse todas as linhas de todas as colunas na tabela. Se você implantar e executar o aplicativo neste ponto, o componente Tabela mostra todas as informações sobre a viagem na tabela TRIP.

Neste aplicativo, o componente Tabela deve exibir somente as informações da viagem da pessoa cujo nome está selecionado no componente Lista suspensa. Você limita as informações exibidas na tabela editando a consulta do objeto tripRowSet para criar um relacionamento mestre-detalhe entre o componente Lista suspensa e o componente Tabela.
  1. Clique na guia tripRowSet (SessionBean1) na área de edição para mudar para o Editor de consultas.
  2. Em Desenhar grade do Editor de consultas, clique com o botão direito do mouse em qualquer célula na linha PERSONID e escolha Adicionar critérios de consulta.
  3. Defina a lista suspensa Comparação como =Equals e selecione o botão de opção Parâmetro.
  4. Clique em OK.

    Na coluna Critérios de PERSONID aparece =?, que adiciona a seguinte expressão WHERE na consulta SQL.

    Amostra de código 1: Expressão WHERE na consulta SQL
    WHERE TRAVEL.TRIP.PERSONID = ?

    Dica para solução de problemas: Neste ponto, você pode verificar se a sua consulta está definida adequadamente. Clique com o botão direito do mouse no Editor de consultas e escolha Executar consulta. Na caixa de diálogo Especificar valores de parâmetros, digite 1 para o valor do parâmetro TRAVEL.TRIP.PERSONID e clique em OK. A saída da sua consulta para a Pessoa 1 está no painel de resultados do editor de consultas.
  5. Em Desenhar grade do Editor de consultas, clique na célula Tipo de classificação na linha DEPDATE para exibir a lista suspensa.
  6. Escolha Crescente na lista suspensa da célula Tipo de classificação.

    O IDE define automaticamente a Ordem de classificação e adiciona a expressão de classificação à consulta SQL.
  7. Feche o Editor de consultas.
  8. No Visual Designer, clique duas vezes no componente Lista suspensa.

    O código-fonte da classe Page1 é aberto no Editor Java e o cursor aparece dentro do corpo do método personIdDD_processValueChange. O IDE cria o stub deste método manipulador de eventos na primeira vez que você clicar duas vezes no componente Lista suspendo.
  9. Substitua o corpo do método personIdDD_processValueChange pelo código que aparece abaixo em negrito.

    Amostra de código 2: Manipulação de eventos de alteração de valor para o componente Lista suspensa
    public void personIdDD_processValueChange(ValueChangeEvent event) {
        try {
           getSessionBean1().getTripRowSet().setObject(
             1, personIdDD.getSelected());
           tripDataProvider.refresh();
         } catch (Exception e) {
           error("Não é possível alternar para a pessoa " +
             personDataProvider.getValue(
             "PERSON.PERSONID"));
           log("Não é possível alternar para a pessoa " +
             personDataProvider.getValue(
             "PERSON.PERSONID"), e);
        }
    }
    

    Este código vincula o valor do PERSONID do NAME atualmente selecionado na lista suspensa ao parâmetro na instrução SQL preparada do objeto tripRowSet, executa a consulta e obtém o novo conjunto de resultados.

    O método setObject substitui o ? da consulta pelo valor do PERSONID. O método refresh envia a nova consulta e atualiza o conjunto de resultados. Para saber mais sobre ambos os métodos, clique com o botão direito na chamada do método e escolha Mostrar Javadoc no menu pop-up. Exibir Provedor de dados e os RowSet Javadocs escolhendo Ajuda > Referências de Javadoc > Provedor de dados e Ajuda > Referências de Javadoc > Conjunto de linhas.

    O método log envia uma mensagem e a pilha de chamadas associada ao registro do servidor de aplicativos para ajudar no reconhecimento e no diagnóstico dos problemas do usuário. Você pode visualizar o registro do servidor clicando com o botão direito do mouse no no nó do servidor na janela Tempo de execução e escolhendo Exibir registro do servidor, no menu pop-up.
  10. Pressione Ctrl-Shift-F para reformatar o código.
  11. Clique na janela Navegador e digite prerender. Logo que você começar a digitar, a caixa de diálogo Pesquisa rápida se abre, como mostrado na figura abaixo. O IDE realça a primeira entrada correspondente no Navegador.

    Observe que a janela Navegador e a janela Esboço compartem o mesmo espaço. Você pode trazer a janela para frente clicando no seu cabeçalho.

    Figura 8: Pesquisa rápida na janela Navegador
    Figura 8: Pesquisa rápida na janela Navegador
  12. Pressione Enter. O Editor Java exibe o método prerender.
  13. Substitua o corpo do método prerender pelo código que aparece abaixo em negrito.

    Amostra de código 3: Sincronizando os dados mestre-detalhe quando a página é exibida pela primeira vez
    public void prerender() {
        if ( personIdDD.getSelected() == null ) {
            try {
              personDataProvider.cursorFirst();
              getSessionBean1().getTripRowSet().setObject(
                1, personDataProvider.getValue("PERSON.PERSONID"));
              tripDataProvider.refresh();
            } catch (Exception e) {
              error("Não é possível alternar para a pessoa " +
                  personDataProvider.getValue("PERSON.PERSONID"));
                log("Não é possível alternar para a pessoa " +
                  personDataProvider.getValue("PERSON.PERSONID"), e);
            }
        }
    }

    Este código, chamado antes que o navegador da Web comece a exibir a página, manipula a situação quando a página é acessada pela primeira vez.
  14. Pressione Ctrl-Shift-F para reformatar o código.
  15. Clique em Design na barra de ferramentas de edição para voltar ao Visual Designer.
  16. Clique com o botão direito do mouse no componente Lista suspensa e escolha Enviar automaticamente ao alterar.

    Na janela Propriedades, aparece o seguinte código na propriedade onchange.

    Amostra de código 4: Código da propriedade onchange
    webuijsf.suntheme.common.timeoutSubmitForm(this.form, 'personIdDD');
    

    A partir de agora, quando o usuário alterar a seleção da lista suspensa no aplicativo da Web em execução, o navegador da Web enviará a página automaticamente.
  17. Clique em Executar projeto principal na barra de ferramentas principal.

    O IDE salva todos os arquivos alterados, reconstrói e reimplanta o aplicativo no servidor.
  18. Selecione um pessoa do componente Lista suspensa para ver como o componente Tabela sincroniza os dados mestre e detalhe. Clique no cabeçalho da coluna DESTCITY para ver como componente Tabela classifica as linhas.

Fazendo mais

Experimente. Adicione um componente Texto estático à direita do componente Lista suspensa. Clique com o botão direito do mouse no componente Texto estático, escolha Vincular aos dados e vincule o componente ao PERSON.JOBTITLE. Execute o programa e escolha outro nome na lista suspensa. Observe que o título do trabalho não se altera. A razão de que não se altere é que o aplicativo precisa sincronizar personDataProvider com o item selecionado na lista suspensa. Adicione o código mostrado abaixo em negrito ao método prerender e execute o aplicativo novamente. Os títulos do trabalho devem corresponder agora ao nome selecionado.

Amostra de código 5: Sincronizando personDataProvider com a pessoa selecionada
public void prerender() {
    if ( personIdDD.getSelected() == null ) {
        try {
            personDataProvider.cursorFirst();
            getSessionBean1().getTripRowSet().setObject(
                1, personDataProvider.getValue("PERSON.PERSONID"));
            tripDataProvider.refresh();
        } catch (Exception e) {
            error("Não é possível alternar para a pessoa " +
                    personDataProvider.getValue("PERSON.PERSONID"));
            log("Não é possível alternar para a pessoa " +
                    personDataProvider.getValue("PERSON.PERSONID"), e);
        }
    }
    else {
        try {
            // Sincronizar o provedor de dados com a seleção atual
            personDataProvider.setCursorRow(
                    personDataProvider.findFirst(
                    "PERSON.PERSONID", personIdDD.getSelected()));
        } catch (Exception e) {
            error("Não é possível alternar para a pessoa " +
                    personIdDD.getSelected());
            log("Não é possível alternar para a pessoa " +
                    personIdDD.getSelected(), e);
        }
    }
}

Experimente. Brinque com as opções de layout da tabela. Clique com o botão direito do mouse no componente Tabela e escolha Layout da tabela no menu pop-up. Altere o Texto do cabeçalho por Data de partida, Cidade de partida, Cidade de destino e Descrição. Use a tabela Opções da caixa de diálogo para definir o título da tabela como Viagens. Selecione Ativar paginação e defina Tamanho da página como 3. Execute o aplicativo e veja como as alterações afetam a forma como a tabela é exibida.

Observação: Se usar a opção de paginação, adicione o seguinte código após a instrução tripDataProvider.refresh() no método personIdDD_processValueChange: tableRowGroup1.setFirst(0);. Isto garante que a primeira página seja sempre exibida quando outro nome for selecionado na lista suspensa.

Experimente. Construa um aplicativo da Web com o componente Lista suspensa e um componente Tabela. Faça com que o componente Lista suspensa exiba TRIPTYPE.DESCRIPTION. Faça com que o componente Tabela mostre todos os registros TRIP que possuam o mesmo TRIPTYPEID como o TRIPTYPE selecionado.

Experimente. Você pode se perguntar se o código duplicado nos métodos prerender e personIdDD_processValueChange provoca atualizações em dobro do conjunto de linhas detalhado. A resposta é não. Para exemplificar, adicione uma instrução log(nome-do-método) ao construtor, ao método prerender e ao personIdDD_processValueChange. Na janela Tempo de execução, clique com o botão direito do mouse em um nó do servidor e escolha Exibir registro do servidor. Execute o programa e selecione um novo nome. No registro do servidor (na janela Esboço), você vê que os métodos são chamados na seguinte ordem:
  1. constructor
  2. prerender
  3. constructor
  4. personIdDD_processValueChange

Quando o navegador solicita a página pela primeira vez, o aplicativo cria uma instância de Page1 e chama prerender. O servidor envia a resposta (a página HTML) e a instância de Page1 é eliminada. O aplicativo não chama o manipulador de eventos de alteração de valor porque o aplicativo gera eventos de alteração de valor somente quando um página é enviada (neste caso, quando uma nova pessoa é selecionada).

Quando você escolhe um novo nome na lista suspensa, o navegador envia a página. O aplicativo cria uma nova instância de Page1 e restaura os valores da instância anterior (eles são passados na solicitação). Por ser um postback (uma inscrição) e devido a alteração do nome, o aplicativo gera um evento de alteração de valor. Assim, personIdDD_processValueChange é chamado e o aplicativo atualiza o conjunto de linhas.

Depois que o manipulador de eventos de alteração de valor é chamado, o aplicativo chama o método prerender. Devido a que a lista suspensa possui agora um valor selecionado, o aplicativo ignora a seção if no método prerender.

Resumo

As etapas para a vinculação de um componente a uma tabela de banco de dados são as seguintes:
  1. Você vincula um componente a uma tabela de banco de dados soltando o nó da tabela de banco de dados no componente ou escolhendo Vincular aos dados no menu pop-up e selecionando um provedor de dados existente na lista suspensa.
  2. A caixa de diálogo Vincular aos dados é usada para configurar as colunas de banco de dados que o componente irá exibir e, em um componente do tipo lista, que coluna ele irá retornar. O menu de ação Layout da tabela também pode ser usado para configurar que colunas da tabela de banco de dados o componente Tabela irá exibir.
  3. Para modificar uma consulta de um objeto RowSet, você abre o Editor de consultas no objeto RowSet da janela Esboço.
  4. Você chama o método setObject do objeto RowSet para definir os valores dos parâmetros de consulta. Você chama o método refresh do provedor de dados para executar a consulta e atualizar o conjunto de resultados.
  5. Use o menu de ação Enviar automaticamente ao alterar para que a página seja enviada automaticamente sempre que o valor de um componente for alterado.
  6. Realize as etapas seguintes para sincronizar um componente detalhe com um componente mestre:

    1. Adicione o código ao método prerender do Bean da página para que chame o método setObject do objeto RowSet detalhe para definir os parâmetros de consulta como padrão, tal como a primeira pessoa em uma lista suspensa. Em seguida, chame o método refresh para executar a consulta.
    2. Vincule o componente mestre a um método processValueChanged. Faça este método chamar o método setObject do objeto RowSet detalhe para definir os novos parâmetros de consulta. Em seguida, chame o método refresh para executar a consulta.

Consulte também:

  • Examinando componentes
  • Ajuda > Referências de Javadoc > Provedor de dados
  • Ajuda > Referências de Javadoc > Conjunto de linhas


Esta página foi modificada pela última vez em 26 de fevereiro de 2007


Bookmark this page

del.icio.us furl simpy slashdot technorati digg
Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Virtual Box - full virtualizer  Open ESB - The Open Enterprise Service Bus Powered by