Friday, January 5, 2018

SOAP Web Services in WildFly

Web services are client and server applications that communicate with each other through the HyperText Transfer Protocol (HTTP). As the name implies, web services represent something accessible on the web that gives you a service. The application that gives a service is called the provider and the one that uses a service is called consumer.

The main advantage of web services is that they provide a standard means of interoperating between software applications running on a variety of platforms and frameworks, i.e., the underlying implementation can be done in any language (Java, PHP, C#, C++, ...). A consumer and a service provider will still be able to exchange data in a loosely coupled way using XML documents.

SOAP (Simple Object Access Protocol) web services are said to be loosely coupled because the client doesn't have to know its implementation details. The communication between them happens by means of XML messages that rely on the SOAP specification which refers to the WSDL (Web Services Description Languages).  The Web Service Description Language is the de facto standard to provide a description of a web service contract exposed to clients. If you want to use (consume) some SOAP based web services you must follow the rules described in its XML, the WSDL document, that describes a web service in terms of the operations that it provides, and the data types that each operation requires as input and can return in the form of results.

Creating a SOAP Web Service in WildFly 10 to validate a CPF

 Open Eclipse IDE and create a New Maven Project. Give it the name SOAP_WS_ValidateCPF, select packaging as .war and Finish:

In the pom.xml add the dependency for JavaEE 8 API. It should be like this:
<project xmlns="" xmlns:xsi="" xsi:schemaLocation="">


Although it's not mandatory, we will create an interface to represent our web service contract. It will have a method that receives a Pessoa as an argument and checks if its CPF field is valid by setting a flag in the field cpfValido, then returns that person to the consumer:
public interface ConsultaCPF {

 public Pessoa consultarCPF( Pessoa pessoa);
And the interface implementation ConsultCPFImpl. We turn that class into a web service just by adding the mandatory @WebService annotation, all others annotations are optional.
@WebService(targetNamespace="", serviceName="ConsultaCPFService")
public class ConsultaCPFImpl implements ConsultaCPF {

 @WebResult(name = "pessoa")
 public Pessoa consultarCPF( @WebParam(name = "pessoa") Pessoa pessoa) {
  //business rules...
  if(pessoa.getCpf() != null && pessoa.getCpf().length() == 11 ){
   String cpf = pessoa.getCpf();
   char ultimoDigito = cpf.charAt(cpf.length()-1);
   int n = new Integer(ultimoDigito);
   boolean par = n % 2 == 0;
  return pessoa;
The hypothetical validation rule just checks if the field is not null and has 11 characters, then validates if the last character is even. The meaning of the other annotations and its parameters are:
  • @WebService(targetNameSpace="xyz"): declare the namespaces for WSDL elements generated by the web service
  • @WebService(serviceName="name"): the name specified is used to generate the name attribute in the service element in the WSDL interface
  • @WebMethod(): indicates that you want to expose this public method as web service
  • @WebParam(): indicates the parameter name that should be exhibited in the WSDL
  • @WebResult(): similar to @WebParam, it specifies the method param name in the WSDL
Of course, we need the entity Pessoa. As stated before, everything exchanged between the consumer and the web service take place as XML file, that means things like java POJOs should be marshaled/unmarshaled to/from an XML format as it is sent/received by consumer and provider. JAXB API does that behind the scenes, all we need to do is annotate the classes and its fields that will be exchanged like following:

@XmlRootElement(name = "pessoa")
public class Pessoa {
 @XmlAttribute(name = "nome")
 private String nome;

 @XmlAttribute(required = true)
 private String cpf;

 @XmlAttribute(name = "nascimento")
 private Date nascimento;

 @XmlAttribute(name = "cpfValido")
 private boolean cpfValido;
//getters & setters...

That's all we need. Now right click on your project, go to properties, then project facets at the right panel, click the runtime tab in the right panel and choose wild fly:

Now right click on your project, choose run as, run on  server... (you might need to clean and build your project or restart wildfly). Check WildFly log and look for this part confirming your web service is already published:

As a compliant JavaEE container, WildFly recognizes, by the @WebService annotation, that your project has web services and automatically creates and publishes the WSDL document. Open WildFly admin console (generally at port 9990), click Runtime tab and navigates through Standalone Server, Subsystems, Web Services and click in view:

Click on WSDL Url to see the generated WSDL XML document exposed representing your web service:

Invoking the Web Service

Since our web service is up and running, it is time to consume it. Make sure to not shutdown wildfly, otherwise the web service won't be accessible anymore.

Create a simple new Java project named SOAP_WS_ValidateCPF_Consumer. Create a class named Main with the main method. At this point, the new project doesn't know nothing about the ConsultaCPFService web service. Java has the utility wsimport under <JAVA_HOME>/bin folder to create the needed artifacts that allow some project to consume a specified web service.

Open your terminal command and go to the source folder of SOAP_WS_ValidateCPF_Consumer project (in my case /home/rafael/workspace/SOAP_WS_ValidateCPF_Consumer/src/) and execute the wsimport utility passing the WSDL Url as a parameter like the picture (you might need root privileges if you are in a Linux environment):

/usr/lib/jvm/jdk1.8.0_144/bin/wsimport -keep -verbose http://localhost:8080/SOAP_WS_ValidateCPF-0.0.1-SNAPSHOT/ConsultaCPFService?wsdl

The wsimport utility imports all needed artifacts to invoke the web service. Refresh your project on eclipse and see that new packages were created in accord with WSDL contract at the URL passes as a parameter:

Now the Main class looks like:

package main;


public class Main {
 //we can get a reference to web service by calling the method getConsultaCPFImplPort()
 ConsultaCPF consultaCPF = new ConsultaCPFService().getConsultaCPFImplPort();
 public static void main(String[] args) {
  new Main();    
 public Main(){
  Pessoa pessoa = new Pessoa();

Run the project. It will return true or false depending on the last digit of CPF field. This small standalone class has shown how it is possible to use SOAP-based services from the client-side perspective.

Now, shutdown wildfly and try to run the Main again. An exception is thrown because the service is not accessible anymore:
Exception in thread "main" Failed to access the WSDL at: http://localhost:8080/SOAP_WS_ValidateCPF-0.0.1-SNAPSHOT/ConsultaCPFService?wsdl. It failed with: 
 Connection refused (Connection refused).
 at main.Main.<init>(
 at main.Main.main(

GONCALVES, Antonio . Beginning Java EE 7 (Expert Voice in Java). 1. ed. New York: Apress, 2013. 608 p.
ĆMIL , Michal; MATLOKA, Michal ; MARCHIONI, Francesco . Java EE 7 Development with WildFly. 2. ed. Birmingham: Packt Publishing Ltd., 2013
JENDROCK, Eric et al. Java Platform, Enterprise Edition: The Java EE Tutorial Release 7. 1. ed. [S.l.]: Oracle, 2014. 980 p.

Thursday, November 16, 2017

Adicionando Opções de Resolução de Tela no Linux

O camando xrandr é um utilitário de configuração do X Window, framework básico para construção de diversos padrões de interfaces gráficas no estilo desktop. O xrandr permite a (re)configuração do X Window dinamicamente, isto é, sem necessidade de reiniciar o servidor. Você também pode obter informações técnicas sobre o monitor e o ambiente gráfico em geral tais como resolução, refresh rate, etc.

Execute camando xandr sem parâmetros e veja todos os outputs (geralmente monitores) conectados ao sistema e alguns detalhes técnicos de cada, como as resoluções:
~ $ xrandr
Screen 0: minimum 8 x 8, current 1680 x 1050, maximum 32767 x 32767
VGA1 connected 1680x1050+0+0 (normal left inverted right x axis y axis) 477mm x 268mm
   1680x1050     59.95*+  
   1280x1024     75.02    60.02  
   1152x864      75.00  
   1024x768      75.03    60.00  
   800x600       75.00    60.32  
   640x480       75.00    59.94  
   720x400       70.08  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
A saída do comando mostra um VGA1 conectado e a resolução marcada com * e + indicam a que está sendo usada no momento e a preferencial, respectivamente.
Com essas informações, você pode definir uma opção de resolução diferente para o monitor (desde que ela esteja disponível). Por exemplo você pode adicionar a resolução 1920x1080 com o seguinte comando:
~ $ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync

Repare em todo trecho que vem após modeline. Copie-o e cole como parâmetro para o comando xrandr:
$ xrandr --newmode "1920x1080_60.00"  118.25  1600 1696 1856 2112  900 903 908 934 -hsync +vsync

Em seguida, execute novamente:
~ $ xrandr --addmode VGA1 "1920x1080_60.00"

A partir deste ponto a nova resolução 1920x1080 já estará disponível em suas configurações de monitor. Caso seu desktop seja um XFCE, por exemplo, você poderá encontrar a nova opção em settings/display a partir do menu inicial, como a janela abaixo:

Wednesday, November 1, 2017

DataSource no servidor WildFly utilizando JPA, JSF, Maven e Eclipse: parte 2

Criando uma aplicação Java para acessar o DataSource

Dando sequência à parte 1 deste artigo onde configuramos o datasource no servidor WildFly 10, agora criamos a aplicação.
Abra o Eclipse e crie um Novo Projeto Maven (File/New/Other.../Maven Project). Marque a opção Create a Simple Project e Next:

Informe as propriedades do projeto e na combobox Packaging escolha war. Finish:

Vá em propriedades do projeto. No painel esquerdo selecione Project Facets. No painel direito marque as opções CDI, JPA e Java Server Faces. Mais à direita, na aba Runtimes marque WildFly. Clique em Apply e OK:

No arquivo pom.xml adicionamos as dependências do JPA (hibernate):
<project xmlns="" xmlns:xsi=""

Na pasta META-INF o eclipse já cria para nós o arquivo persistence.xml dentro do qual informamos alguns parâmetros do JPA, como o nome do data source no servidor, instruímos a gerar tabelas no banco de dados a partir das classes do projeto e mostrar os scripts SQL por exemplo.

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.1"
 xmlns="" xmlns:xsi=""

 <persistence-unit name="TestDataSource">

   <property name="javax.persistence.schema-generation.database.action"
    value="none" />
   <property name="hibernate.format_sql" value="true" />
   <property name="hibernate.show_sql" value="true" />
   <property name="" value="update" />

Entidade Funcionario

Agora que o projeto já está configurado, crie  pacote chamado entidades e nele a classe Funcionario como segue. A anotação @Entity informa ao JPA que essa classe será uma tabela no banco de dados:
public class Funcionario implements Serializable{

 @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id; //chave primaria da tabela 
 private String nome;

 private Integer idade;

 private Date nascimento;

 private Double salario;
 //getters, setters omitidos para clareza

Até o momento a estrutura do nosso projeto está como na imagem:

Página JSF e Managed Bean

Crie um pacote chamado controle e nele a classe chamada FuncionarioMB e FuncionarioService, onde esta é responsável por intermediar as ações com o banco de dados (salvar, editar, excluir, etc) e aquela gerencia os eventos na interface gráfica com o usuário, neste caso a página web:

FuncionarioMB (gerencia os eventos na web page):
import java.util.List;
import javax.inject.Inject;
import javax.enterprise.inject.Model;
import javax.transaction.Transactional;
import entidade.Funcionario;

public class FuncionarioMB {

 private FuncionarioService funcionarioService; 
 private Funcionario funcionario = new Funcionario();
 private List<Funcionario> funcionarios;  
 //diz para o servidor wildFly abrir transação para persistir objeto no banco
 //o próprio servidor faz o commit após o método retornar
 public String salvar() {  
  return null;
 public Funcionario getFuncionario() {

  return funcionario;

 public void setFuncionario(Funcionario funcionario) {
  this.funcionario = funcionario;

 public List<Funcionario> getFuncionarios() {
  //busca todos os registros na tabela e exibe
  if(funcionarios == null)
   funcionarios = funcionarioService.buscarTodos();
  return funcionarios;

FuncionarioService (camada de serviço e acesso ao banco de dados):

package controle;

import java.util.List;
import javax.enterprise.inject.Model;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import entidade.Funcionario;

public class FuncionarioService {

 private EntityManager entityManager;
 public void salvar(Funcionario funcionario) {

 public List<Funcionario> buscarTodos() {

  String query = "SELECT f FROM Funcionario f";
  return entityManager.createQuery(query).getResultList();

Agora podemos criar a web page. No diretório src/main/webapp crie a pasta index.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns=""

  <h:outputText value="Cadastro de Funcionário" />
  <h:panelGrid columns="2">
   <h:outputText value="Nome" />
   <h:inputText value="#{funcionarioMB.funcionario.nome}" />
   <h:outputText value="Idade" />
   <h:inputText value="#{funcionarioMB.funcionario.idade}" />       
   <h:outputText value="Salário" />
   <h:inputText value="#{funcionarioMB.funcionario.salario}" >
    <f:convertNumber pattern="#0.00" locale="pt"/>
   <h:outputText value="Data Nascimento" />
   <h:inputText value="#{funcionarioMB.funcionario.nascimento}" >
    <f:convertDateTime pattern="dd/MM/yyyy" locale="pt" />
   <h:commandButton action="#{funcionarioMB.salvar()}" value="Salvar" />
  <h:dataTable value="#{funcionarioMB.funcionarios}" var="funcionario" border="1">
    <h:outputText value="#{funcionario.nome}" />
    <h:outputText value="#{funcionario.idade}" />
    <h:outputText value="#{funcionario.salario}" >
     <f:convertNumber pattern="#0.00" currencySymbol="$" locale="pt"/>
    <h:outputText value="#{funcionario.nascimento}" >
     <f:convertDateTime pattern="dd/MM/yyyy" locale="pt" />
Todo input de texto em aplicações web são interpretados por padrão como texto puro, dessa forma utilizamos alguns converters padrão do JSF para a adpatar os tipos de dados que não são texto, como a idade, nascimento, e salário.
Pronto. A aplicação já está pronta para rodar. Clique com o botão direito na pasta raíz da aplicação, escolha Run as, em seguida Run on Server. A aplicação será acessada na porta default do servidor, geralmente a 8080:

Insira registros válidos (como nenhuma regra de validação foi implementada, se você inserir registros inválido, a aplicação vai lançar um erro) e salve. A tabela lista os funcionário cadastrados até o momento.
A estrutura final do projeto ficou como segue:

Wednesday, October 18, 2017

DataSource no servidor WildFly utilizando JPA, JSF, Maven e Eclipse: parte 1

Aplicações Java Enterprise acessam banco de dados utilizando a API JDBC. Nela os bancos de dados são acessados usando objetos do tipo DataSource, os quais possuem uma série de propriedades que identificam o banco de dados real como a URL do servidor, o nome do banco de dados, senha, etc.

Antes de acessar o banco de dados, a aplicação precisa criar uma conexão, e um objeto DataSource funciona como um factory de conexões entre o banco e a aplicação. Quando o DataSource é gerenciado pelo servidor de aplicações, geralmente a ele é associado um JNDI, que é um nome para o datasource. Assim quando a aplicação demanda uma conexão, ela utiliza o JNDI, o servidor instancia o(s) objeto(s) DataSource e disponibilizam a conexão.

Datasources em servidores Java EE geralmente implementam o poolingque são algoritmos de instanciação de DataSources totalmente transparentes à aplicação os quais otimizam a liberação, abertura e fechamento de conexões com o banco de dados.

DataSources para o banco de dados MySQL no servidor WildFly 10

Faça download da API JDBC do MySQL (mysql-connector-java-5.1.21.jar) e, caso necessário, baixe também o servidor WildFly 10 Java EE7 Full & Web Distribution . No MySQL, crie um banco de dados chamado EmpresaBD.

No WildFly, DataSources também são chamados de módulos. Assim, para acessar o MySQL do servidor precisamos instalar um novo módulo para ele. No diretório raiz do WildFly, há a pasta modules. A partir dela crie os diretórios /com/mysql/main/ da forma que segue:


Dentro da pasta main cole o driver do MySQL que você acabou de baixar e crie um arquivo chamado module.xml, o qual conterá a definição do módulo cujo nome é com.mysql. 

A variável JBOSS_HOME aponta para pasta module e os arquivos e pastas criados lá dentro serão usados para carregar o datasource quando o servidor iniciar. O conteúdo do arquivo module.xml deve ser como segue:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.mysql"> 
        <resource-root path="mysql-connector-java-5.1.21.jar"/>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>

Salve e feche o arquivo module.xml. A estrutura de diretórios que criamos então fica dessa forma:
  • WILDFLY_HOME/modules/com/mysql/main/mysql-connector-java-5.1.21.jar
  • WILDFLY_HOME/modules/com/mysql/main/module.xml

O módulo que permite acessar o MySQL do WildFly está instalado. Agora só precisamos criar o data source para o banco EmpresaDB. Para isso temos que editar o arquivo standalone.xml passando as coordenadas do banco (usuário, senha, etc.). Esse arquivo está localizado em:
  • WILDFLY_HOME/standalone/configuration/standalone.xml 
Abra esse arquivo, localize a tag <dataSources> e dentro dela cole o seguinte trecho (ajustando usuário e senha de acordo com suas configurações pessoais):
<datasource jta="true" jndi-name="java:jboss/datasources/empresaDB_DS_mysql"
 pool-name="empresaDB_DS_mysql" enabled="true">



Ainda dentro da tag <dataSources> localize a tag <drivers> e dentro dela cole este trecho:
<driver name="mysql" module="com.mysql"/>
Repare que a tag driver aponta para o módulo que criamos. E o datasource que criamos aponta para a esta tag driver cujo nome é mysql.

Salve e feche o arquivo standalone.xml. Pronto. Inicie o servidor WildFly executando o arquivo (para Linux) ou standalone.bat (para Windows) localizado em WILDFLY_HOME/bin/

Acesse o console do servidor na porta 9990. Clique na aba Configurations, depois vá clicando em Subsystems, DataSources, Non-XA. Localize o datasource criado EmpresaDB_DS_mysql e teste a conexão. Conforme a imagem:

Repare que o nome que registramos, empresaDB_DS_mysql, é o que será usado na aplicação para que ela solicite ao servidor uma conexão com o banco de dados EmpresaDB.

Na parte 2 deste artigo criamos uma aplicação JavaEE que acessa o DataSource.

ĆMIL , Michal; MATLOKA, Michal ; MARCHIONI, Francesco . Java EE 7 Development with WildFly. 2. ed. Birmingham: Packt Publishing Ltd., 2013

Access restriction: The type 'Application' is not API (restriction on required library '/usr/lib/jvm/jdk1.8.0_144/jre/lib/ext/jfxrt.jar')

Recentemente ao criar um projeto JavaFX no Eclipse, a IDE disparava uma advertência sempre que eu tentava importar algo do pacote javafx.*

Para corrigir isso, vá em propriedades do projeto. Na janela que abrir selecione Java Build Path, vá na tab libraries e expanda o item JRE System Library, conforme a imagem:

Selecione o item Access Rule e depois o botão Edit.... Na janela que abrir clique no botão Add... .Na caixa de texto Rule Pattern coloque javafx/** e na combo box Resolution escolha a opção Accessible Conforme a imagem:

Clique em OK, Apply e OK. Limpe e construa seu projeto novamente. As advertências deixam de aparecer.

Monday, October 16, 2017

Generic Lazy Loading com JSF e PrimeFaces

Lazy Loading é um padrão de projeto que atrasa o carregamento de dados na memória até o momento quando eles são estritamente necessários. Em sistemas orientados a objeto, as entidades estão sempre relacionadas umas com as outras de modo que esses níveis de relacionamento podem se extender indefinidamente dependendo do tamanho do sistema. Se a aplicação não implementa uma estratégia adequada para listar os registros em uma tabela, ela corre o risco de carregar uma quantidade absurda de dados na mémória sem necessidade, o que pode prejudicar seu desempenho.

O componente p:dataTable do framework PrimeFaces permite implementar LazyLoading de forma muito simples bastando que o desenvolvedor estenda LazyDataModel<T>, onde T é o tipo da entidade que será carregada na tabela. Por exemplo, suponha que você tenha uma entidade Pessoa, você deveria extender LazyDataModel da seguinte forma:
public class LazyTablePessoa extends LazyDataModel<Pessoa>{

   private PessoaService service;

   public List<Pessoa> load(int first, int pageSize, String sortField, 
                               SortOrder sortOrder, Map<String, Object> filters) {

        List<Pessoa>listPessoa = pessoaService.getPessoas(first, first + pageSize);
        int linhas = pessoasService.countPessoas();
        return listPessoa;
  //... outros métodos
Essa abordagem possui um problema se o projeto for crescendo e um número cada vez maior de entidades demandar lazy loading em determinadas telas. Dessa forma seria necessário implementar  LazyDataModel para cada entidade que você queira exibir. Se houver 100 entidades para listar, você terá que implementar 100 extensões de LazyDataModel, cada uma com o código praticamente idêntico!

Generic Lazy Data Table
Somente os dados exibidos são carregados na memória.

Podemos reduzir drasticamente essa quantidade de implementações criando uma única extensão genérica de LazyDataModel que atenda, digamos, 90% de todas as necessidades de exibição, ou seja, você podera ter 100 entidades no seu modelo, mas uma única implementação de LazyDataModel será suficiente para listar as entidade de acordo com o padrão lazing.

Para implementar este padrão precisamos criar:
  1. Uma DataTable genérica que extenda LazyDataModel
  2. Uma interface de serviço genérica que busque os dados. As especificações de busca para cada entidade variam de acordo com a implementação.
O diagrama de classes abaixo resume o modelo:

Implementando o diagrama
public class Pessoa {
    private String nome;
    private int idade;
    private Date nascimento;

    //métodos getters & setters
public interface GenericService<T> {
    //a quantidade de registros que serão carregados
    List<T> buscaPaginada(int inicio, int fim);
    //a quantidade de registros na fonte de dados
    int countLinhas();
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class PessoaService implements GenericService<Pessoa>{

    //representando o banco de dados
    private List<Pessoa> dataSource;
    public PessoaService() {

        dataSource = new ArrayList<>();
        for(int i = 0; i < 100; i++){
            Pessoa p = new Pessoa();
            p.setNome("Pessoa "+i);
            p.setNascimento(new Date());

    //implementação para a entidade pessoa
    //as regras podem variar de entidade para entidade...
    public List<Pessoa> buscaPaginada(int inicio, int fim) {        

        return dataSource.subList(inicio, fim);

    public int countLinhas() {

        return dataSource.size();

Nossa implementação de GenericLazyDataTable. Repare que o tipo do objeto é genérico (T), ou seja, a princípio não se sabe qual é o tipo de objeto sendo buscado nem qual é o critério de busca, que
dependerá da implementação fornecida para a interface GenericService.

import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

public class GenericLazyDataTable<T> extends LazyDataModel<T>{
    private final GenericService genericService;

    public GenericLazyDataTable(GenericService genericService) {

        this.genericService = genericService;

    public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {

        int linhas = genericService.countLinhas();
        return genericService.buscaPaginada(first, first + pageSize);

O managed bean controller da página JSF
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

public class ManagedBean implements Serializable{
    private GenericLazyDataTable genericLazyDataTable;
    private GenericService genericService;    

    public void init(){        

        genericService = new PessoaService();
        genericLazyDataTable = new GenericLazyDataTable(genericService);

    public GenericLazyDataTable getGenericLazyDataTable() {

        return genericLazyDataTable;

E a página inicial index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">

<html xmlns=""
        <title>Lazy Pessoa</title>

        <p:dataTable value="#{managedBean.genericLazyDataTable}" var="pessoa" lazy="true" rows="20" paginator="true">

            <p:column headerText="nome">
                <h:outputText value="#{pessoa.nome}" />

            <p:column headerText="idade">
                <h:outputText value="#{pessoa.idade}" />

            <p:column headerText="nascimento">
                <h:outputText value="#{pessoa.nascimento}" >
                    <f:convertDateTime pattern="dd/MM/yyyy" locale="pt" />


Estrutura do projeto na IDE NetBeans 8.1 (utilizando Maven)

Tornando a implementação ainda mais genérica

É possível tornar esse modelo ainda mais genérico. Por exemplo poderíamos criar um campo Map em GenericLazyDataTable e sobrecarregar o método buscaPaginada de GenericService para definir filtros de busca. Algo como: 
private Map<String, Object> filtrosPersonalizados;

//outros campos...

//pode ser chamado pelo Managed Bean
public void adicionarFiltro(String nomeDocampo, Object tipoDoCampo) {

        filtrosPersonalizados.put(campo, object);

Friday, July 28, 2017

Atualizando a variável JAVA_HOME no Linux

JAVA_HOME é uma variável de ambiente que aponta um diretório JDK no seu sistema. Essa variável é utilizada como referência por vários aplicativos que usam o java para rodar. Se ela não existir ou estiver incorretamente configurada, muitos aplicativos podem não executar.

O arquivo home/.bashr contém o script the execução além de vários parâmetros para iniciar o shell bash, que é a versão mais comum em Linux para terminais de linhas de comando. Para atualizar a JAVA_HOME anexamos o camando export no final do arquivo .bashr junto com o novo valor da variável.

Suponha que você baixou a última versão do JDK, que hoje é jdk1.8.0_141, no diretório:


Utilizando o editor de texto vi, abra o arquivo .bashr
vi .bashr
Adicione no final do arquivo os camandos:

export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_141/
export PATH=$JAVA_HOME/bin:$PATH

No final do arquivo adicionamos o novo valor de JAVA_HOME e exportamos para o PATH
Variáveis de ambiente e de shell são definidas através do comando export. A última linha adiciona a variável JAVA_HOME na variável PATH, a qual mapeia todos os comandos reconhecidos pelo terminal shell bash.

Observação: o editor de texto vi funciona em dois modos, comando e inserção, caso você tenha alguma dificuldade, dê uma olhada aqui. Ou você também pode utilizar outro editor de texto, como o nano por exemplo.

Salve e feche o arquivo. Efetive as mudanças que você acabou de realizar no arquivo .bash utilizando o camando source:
source ~/.bashrc
Pronto! Agora imprima o valor de JAVA_HOME. A saída deve ser semelhante à do comando  java -version:
$ echo $JAVA_HOME
$ java -version
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)
Seu java está atualizado.