Java e PostgreSQL: Como instalar pacotes JAR

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (0)  (0)

Descrição e demonstração da montagem, instalação e manipulação dos pacotes JAR e das classes Java desenvolvidas pelo usuário do banco de dados para serem utilizados em conjunto com as funções da linguagem procedural do PostgreSQL.

[lead]

De que trata o artigo:

Descrição e demonstração da montagem, instalação e manipulação dos pacotes JAR e das classes Java desenvolvidas pelo usuário do banco de dados para serem utilizados em conjunto com as funções da linguagem procedural do PostgreSQL.

Para que serve:

Descrever a estrutura de um pacote JAR manipulado pelo PL/Java, bem como mostrar como construir o arquivo deployment descriptor para uma instalação/remoção/atualização automática da estrutura adjacente às classes Java. Descreve também como instalar e manipular os pacotes e classes Java depois de instalados na base de dados.

Em que situação o tema é útil:

Possibilidade de migração das regras de negócio, escritas em Java, da camada de aplicação para o banco de dados, aumentando os recursos do mesmo com a utilização e manipulação direta dos dados pelo Java.[/lead]

Neste artigo, daremos inicio a uma nova série sobre a utilização da linguagem procedural PL/Java do PostgreSQL. Em edições anteriores da SQL Magazine (72 e 73) tivemos dois artigos sobre o tema. No primeiro deles descrevemos algumas características da linguagem e no segundo mostramos como preparar um servidor de banco de dados para utilizar o PL/Java no desenvolvimento das funções.

Neste primeiro artigo desta nova série, pretendemos descrever a estrutura de um pacote JAR criado pelo usuário, com suas classes Java, para ser carregado na base de dados. Mostraremos como escrever o deployment descriptor para fazer a instalação automática de toda estrutura adjacente das classes Java, bem como as funções de instalação e manipulação dos pacotes JAR.

A versão do PL/Java aqui discutida é a 1.4.0, com o PostgreSQL na versão 8.3.7 em ambiente Linux (CentOS 5.2).

[subtitulo]Estrutura dos pacotes JAR[/subtitulo]

Antes de mostrar alguns exemplos práticos de como escrever as funções utilizando o PL/Java, é necessário entendermos alguns aspectos referentes à própria instalação das classes Java desenvolvidas pelo usuário.

Todos os exemplos mostrados a partir deste ponto serão baseados em funções e classes Java disponibilizadas em um pacote JAR chamado examples.jar (ler Nota DevMan 1). Este pacote é criado junto com os arquivos de instalação do PL/Java. Em nosso ambiente de demonstração, que montamos no artigo publicado na SQL Magazine 73, o pacote JAR foi instalado no diretório /var/lib/pgsql/pljava, conforme pode ser visto na Figura 1.

[nota]Nota DevMan 1. Pacote JAR

É um arquivo compactado usado para distribuir um conjunto de classes Java. É usado para armazenar classes compiladas e metadados associados que podem constituir um programa. Podem ser criados e extraídos usando o utilitário jar da JDK, bem como ferramentas de compressão (como o Winzip).[/nota]

Figura 1. Localização do pacote JAR examples.jar.

Toda classe Java desenvolvida pelo usuário, e que será usada pelas funções do PL/Java, deve ser instalada na base de dados através de um pacote JAR. Na Figura 2 podemos ver a estrutura geral do JAR que é utilizado pelo PL/Java e na Figura 3, a estrutura do arquivo examples.jar. Esta estrutura é semelhante a um arquivo EAR (ler Nota DevMan 2).

[nota]Nota DevMan 2. Arquivo EAR

É um formato de arquivo usado pelo Java EE (Java Enterprise Edition) para empacotar um ou mais módulos de uma aplicação em um único arquivo. Com isso, a aplicação destes módulos em um servidor de aplicação pode acontecer de maneira simultânea e segura. Arquivos EAR possuem um arquivo XML que descreve como os módulos serão aplicados. Um arquivo EAR tem a mesma estrutura de um arquivo JAR, com uma ou mais entradas que representam os módulos de uma aplicação e um diretório de metadados, chamado META-INF, que contém um ou mais descritores de aplicação.[/nota]

Figura 2. Estrutura geral de um pacote JAR do PL/Java.

Figura 3. Estrutura do pacote examples.jar.

O diretório de classes é a única estrutura de diretórios obrigatória no arquivo JAR. Este diretório vai seguir o mesmo padrão de definição de um pacote Java, como por exemplo, a classe Security, do arquivo examples.jar, que tem a definição de pacote org.postgresql.pljava.example. Todas as classes deste arquivo estão neste diretório (Figura 3).

O arquivo deployment descriptor é opcional. Diferente do deployment descriptor para Java, que é no formato XML, este arquivo contém comandos SQL, ou seja, é um arquivo de script SQL, com entradas específicas, que diz ao PL/Java o que fazer quando o arquivo JAR é instalado ou removido da base de dados. Ele nada mais é do que um arquivo texto que descreve como e o que criar/remover do database, podendo manipular esquemas, tabelas, índices, funções, triggers e etc.

Este arquivo pode ficar dentro de um diretório, como no arquivo examples.jar (Figura 3), ou na raiz do arquivo JAR, como na Figura 2. Pode ser usada qualquer extensão para o arquivo, ou até mesmo sem extensão. Na Figura 3 podemos observar que o deployment descriptor está no diretório deployment, com o nome examples.ddr. A próxima seção mostrará como escrever o seu conteúdo.

O diretório META-INF também é opcional. Caso o deployment descriptor seja usado, é necessário que exista este diretório com um arquivo Manisfest (ler Nota DevMan 3). Este arquivo tem o nome MANIFEST.MF e tem a função de informar onde está localizado o deployment descriptor. O arquivo Manifest, para o PL/Java, deve conter as informações mostradas na Listagem 1. A Listagem 2 mostra o conteúdo do arquivo MANIFEST.MF de examples.jar.

[nota]Nota DevMan 3. Arquivo Manifest

Determina o funcionamento de um arquivo JAR. Ele é apenas um documento de texto que pode indicar a classe principal de uma aplicação, bem como outros arquivos necessários para que a aplicação funcione. A especificação do formato JAR define como obrigatório apenas a existência do arquivo Manifest, com o nome MANIFEST.MF, em um diretório chamado META-INF. O arquivo Manifest segue a especificação definida pela Sun Microsystems.[/nota]

Cada linha no arquivo Manifest possui o formato palavra-chave: valor. A linha 1 da Listagem 2 informa a versão do arquivo Manifest (seguindo a especificação da Sun Microsystems). A linha 2 indica a localização do deployment descriptor e qual o arquivo que será usado.

A linha 3 mostra a palavra-chave SQLJDeploymentDescriptor. Esta por sua vez, diz ao PL/Java que o arquivo especificado pela palavra-chave Name, na linha 2, é o deployment descriptor do arquivo JAR que está sendo instalado na base de dados.

Verifique a seção Links para mais informações sobre a especificação de um arquivo Manifest e pacotes JAR.

Listagem 1. Formato do arquivo Manifest.

Name: <Localização do deployment descriptor dentro do arquivo JAR>
  SQLJDeploymentDescriptor: TRUE

Listagem 2. Conteúdo do arquivo MANIFEST.MF do arquivo examples.jar.

  1. Manifest-Version: 1.0
  2. Name: deployment/examples.ddr
  3. SQLJDeploymentDescriptor: TRUE

Estrutura do Deployment Descriptor

Quando criamos um arquivo JAR e desejamos que uma sequência de comandos (SQL ou não) seja executada durante a instalação/remoção do JAR na base de dados, precisamos criar e incluir o arquivo deployment descriptor, criando assim, um arquivo auto-instalável/removível. A especificação da estrutura deste arquivo é descrita na Listagem 3.

As ações/comandos que são executados se dividem em dois grupos: um grupo de ações de instalação e outro de remoção. Estas ações são manipuladas pelas funções install_jar, replace_jar e remove_jar, que estão instaladas no esquema sqlj. Estas funções serão descritas com mais detalhes na seção seguinte.

A função install_jar executa o grupo de ações de instalação. A função remove_jar manipula o grupo de ações de remoção. Já a função replace_jar age sobre os dois grupos de ações, executando as ações de remoção e depois as de instalação.

Listagem 3. Estrutura do arquivo deployment descriptor.

SQLActions[]={"<grupo de ações>" [,"<grupo de ações>"]}
   
  onde <grupo de ações> é:
  <ações de instalação> | <açoes de remoção>
   
  <ações de instalação> é:
  BEGIN INSTALL [<comando>;]... END INSTALL
   
  <açoes de remoção> é:
  BEGIN REMOVE [<comando>;]... END REMOVE
   
  <comando> é:
  <SQL | gerenciamento do BD> | <tag de implementação>
   
  <tag de implementação> é:
  BEGIN <id da tag> <SQL | gerenciamento do BD> END <id da tag>
   
  <id da tag> é:
  postgresql
  oracle
  sybase e etc. 

Cada grupo de ação é opcional, onde podemos ter o grupo de ações de instalação sem ter o de remoção e vice-versa. Além disso, toda a escrita no arquivo é case insensitive.

Cada grupo de ação inicia com as palavras-chave begin install (para instalação) ou begin remove (para remoção), seguido do bloco de comandos que serão executados durante a instalação/remoção do arquivo JAR, e finaliza com as palavras-chaves end install ou end remove.

A Listagem 4 mostra um exemplo completo de um deployment descriptor, onde podemos ver, na linha 2, o início do bloco das ações de instalação com os comandos que serão executados quando o pacote JAR for instalado na base de dados. A linha 3 mostra uma tag de implementação, que modifica um parâmetro do PostgreSQL. Temos também a criação de uma função nas linhas 4 e 5 e o final das ações de instalação na linha 6. As linhas de 7 a 9 mostram as ações de remoção. A Listagem 5 mostra partes do arquivo examples.ddr do pacote JAR examples.jar.

Listagem 4. Exemplo completo de um deployment descriptor.

  1. SQLActions[ ] = {
  2.   "BEGIN INSTALL
   
  3.     BEGIN PostgreSQL SET search_path TO locadora END PostgreSQL;
   
  4.     CREATE FUNCTION getRelAnual(int) RETURNS float8
  5.       AS 'Locadora.getRelAnual(int)' LANGUAGE java;
   
  6.   END INSTALL",
   
  7.   "BEGIN REMOVE
  8.     DROP FUNCTION getRelAnual(int);
  9.   END REMOVE"}

Listagem 5. Partes do arquivo examples.ddr do pacote examples.jar.

SQLActions[ ] = {
       "BEGIN INSTALL
           CREATE SCHEMA javatest;
           BEGIN PostgreSQL SET search_path TO javatest,public ENd postgreSQL;
   
           CREATE FUNCTION javatest.java_getTimestamp()
                RETURNS timestamp
                AS 'org.postgresql.pljava.example.Parameters.getTimestamp'
                LANGUAGE java;
           
           ...  
   
           CREATE TABLE javatest.username_test
                (
                name     text,
                username text not null
                ) WITH OIDS;
           
           ...
   
           CREATE TRIGGER insert_usernames
                BEFORE INSERT OR UPDATE ON username_test
                FOR EACH ROW
                EXECUTE PROCEDURE insert_username (username);
   
           ...
   
       END INSTALL",
   
       "BEGIN REMOVE
           DROP SCHEMA javatest CASCADE;
       END REMOVE"
  }

O comando executado dentro do bloco de ações pode ser de três tipos:

  • Comandos SQL de manipulação de dados (DML) e/ou de estrutura (DDL);
  • Comandos de gerenciamento do banco de dados como, por exemplo, o comando SET para modificar/atribuir um valor para um parâmetro do servidor;
  • Tags de implementação – Consiste em um comando SQL ou de gerenciamento de banco de dados. Cada tag possui um único comando por vez.

A ideia por trás da utilização da tag de implementação é escrever comandos (SQL ou não) que são específicos do SGBD onde as classes estão sendo instaladas. Por exemplo, os comandos abaixo só serão executados sem erros no PostgreSQL:

SET search_path TO javatest,public;
  insert into tb_teste values (now(), 1); 

Se o pacote JAR for instalado apenas em bases do PostgreSQL, estes comandos poderão ser escritos fora de uma tag de implementação. Mas se tentarmos instalar o JAR em outros SGBDs, ocorrerão erros, pois os comandos estão utilizando partes de código que não fazem parte do padrão SQL, como a função now(), do comando INSERT.

Para resolver este problema, foi criada a tag de implementação onde é passado o identificador da tag (<id da tag>), que nada mais é do que o nome do SGBD em que o pacote JAR está sendo instalado. Podem existir várias tags de implementação para SGBDs diferentes no mesmo deployment descriptor. Cada comando dentro da tag só será executado para o SGBD específico onde o PL/Java está instalado.

A Listagem 6 mostra um exemplo com os comandos acima dentro das tags de implementação, junto com tags de outros SGBDs. Neste caso, como o PL/Java está instalado no PostgreSQL, quando o deployment descriptor for executado, somente as tags com identificador igual a postgresql serão executadas. O identificador da tag também é case insensitive.

Listagem 6. Exemplos de tags de implementação em um deployment descriptor.

...
  BEGIN PostgreSQL SET search_path TO javatest,public END PostgreSQL;
  BEGIN PostgreSQL insert into tb_teste values (now(), 1) END PostgreSQL;
  BEGIN Oracle create tablespace data datafile '/home/oracle/databases/ora10/data.dbf'
  size                                  10M
  autoextend on maxsize                200M
  extent management local uniform size  64K END Oracle;
  ... 

Com o que foi explicado podemos questionar o seguinte: se o PL/Java é para o PostgreSQL, porque existe a tag de implementação para outros SGBDs?

A resposta para esta pergunta é simples. Uma das grandes vantagens do Java é a portabilidade. O engine do PL/Java é escrito em Java, sendo possível desenvolver novas interfaces, classes e métodos no engine, para serem utilizados em outros SGBDs.

As classes desenvolvidas e empacotadas em arquivos JAR também aderem a esta facilidade, utilizando a linguagem Java para serem utilizadas em qualquer ambiente. Com isso, não necessitamos criar um arquivo JAR para cada banco, basta utilizar as tags de implementação para comandos específicos do SGBD.

[subtitulo]Estrutura do esquema SQLJ[/subtitulo]

No artigo publicado na SQL Magazine 73, mostramos um dicionário de dados de todo o esquema sqlj"

A exibição deste artigo foi interrompida :(
Este post está disponível para assinantes MVP

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?