Category Archives: Java

Packt> uma alternativa a livros caros?

Livro

Designing Hexagonal Architecture with Java: An architect’s guide to building maintainable and change-tolerant applications with Java and Quarkus

Hoje apareceu um tweet sobre esse livro aí. Nele havia um link para a Amazon, que oferecia o livro físico a $39.90 e o Kindle a R$ 150,09. Pra nós, da colônia, é muita grana. Ou pelo menos pra mim é.

Como bom indignado do século XXI, desabafei no próprio twitter e recebi um replay da editora Packtpub me oferecendo uma alternativa à compra do livro.

Pra quem não conhece,

Packt é uma editora fundada em 2003 com sede em Birmingham, Reino Unido, e escritórios em Mumbai, Índia. Packt publica principalmente livros e vídeos impressos e eletrônicos relacionados à tecnologia da informação, incluindo programação, web design, análise de dados e hardware.

A alternativa oferecida foi a assinatura da plataforma com 10 dias de trial. Segundo o site https://subscribe.packtpub.com/, a assinatura dá acesso a mais de 7.500 livros online e videos relacionados à tecnologia.

O plano mais “barato” custa $ 9.99 por mês. Porém, parece realmente que há bastante conteúdo e vale a pena ao menos testar o serviço.

Vou assinar, testar nesses 10 dias de trial e resumir a experiência em outro post aqui.

Até.

How update or add JVM args to Wildfly Server on Eclipse

The configuration file that holds JVM args is called standalone.conf and it’s located in bin folder.

However, if we attach the server to the Eclipse, you must to access other location to do that.

First, you must double-click on server instance name on Server tab. It will open the configuration tab.

After, click on Open launch configuration option and modify and/or add JVM args. Like this.

That’s it.

Lixo

Garbage Collector (GC)

Java é considerada uma managed languaged e, portanto, os objetos que são criados e armazenados no Heap são automaticamente liberados da memória quando um processo especial os elege para tal.

Esse processo é conhecido como Garbage Collector (coletor de lixo) e

…foi inventado por John McCarthy por volta de 1959 para resolver problemas de gerenciamento manual de memória em Lisp.

Linguagens como C e C++ não possuem este mecanismo e a responsabilidade pela liberação de memória fica com o programador, que deve invocar o método free para os objetos que não serão mais utilizados. Algo parecido ocorre em Visual Basic, mas nela o programador deve apontar o objeto para null.

O mecanismo do GC em Java é simples: se um objeto não puder ser alcançado por uma referência a ele na Stack, então ele será marcado como elegível para coleta. Objetos estáticos, cujas referências ficam no Metaspace, nunca serão eleitos pois nunca perdem a referência.

Embora seja automático e executado em uma Thread independente, é possível invocar o processo por meio do método System.gc(). Entretanto essa chamada apenas sugere que o GC seja executado. Sua execução fica a cargo da JVM, que decidi fazê-lo ou esperar por outro momento mais oportuno.

Na versão 1.8 e anteriores, a JVM alocava a quantidade de memória definida na variável -Xms e mesmo após a execução o GC essa memória permanecia alocada. A partir do Java 11, é possível que a memória seja liberada e devolvida ao sistema operacional. Por questões de performance pode ser que isso não ocorra.

Essa diferença de comportamento nas versões é interessantíssima. Abaixo segue um gráfico mensal de uso de memória de uma aplicação Web na versão 1.8 do Java.

Gráfico de uso de memória

Como pode-se observar, a quantidade de memória apenas diminui para o patamar inicial em momentos de reinício do servidor, ocorrido entre 01/12 e 03/12. Quem não conhece o mecanismo, pode achar que ele não está sendo executado ou ocorrendo alguma falha.

A chamada manual do método System.gc() pode resultar em perda de performance, uma vez que ele utiliza recursos da JVM que estariam alocados na aplicação. Portanto é sugerido que a execução do GC seja feita de forma automática e controlada pela JVM.

Mas o que ocorre após os objetos estarem elegíveis para serem coletados pelo GC? Até a versão 1.9 do Java, o método Object.finalize era chamado antes dos objetos serem removidos fisicamente do Heap. Nas versões superiores ele foi marcado como @deprecated. Há um problema em relação a este método: não há garantia do momento de sua execução. Imagine que ele seja chamado para liberar algum recurso mas a aplicação terminar antes. O recurso ficará em execução ou aberto.

Esse post foi uma explicação do que o GC é, como funciona, quando e por quem é chamado. Além de apresentada uma armadilha na sua execução.

Em outros, retomarei a falar de memória e performance.

Até.

Fontes:

https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#gc()

https://www.udemy.com/course/java-application-performance-and-memory-management

https://pt.wikipedia.org/wiki/Coletor_de_lixo_(inform%C3%A1tica)

Effective Java – Item 10 – Sobrescrever o método Equals (parte 1)

Por vezes é melhor herdar o método equals da classe Object do que sobrescrevê-lo.

Para que funcione de forma correta, o equals deve obedecer a um contrato geral, que define que ele seja:

• Reflexivo: x != null => x.equals(x) == true;
• Simétrico: x != null & y != null => x.equals(y) == true <=> y.equals(x) == true ;
• Transitivo: x != null & y != null & z != null => x.equals(y) == true & y.equals(z) == true & x.equals(z) == true;
• Consistente: x != null & y != null => x.equals(y) == true (|| false), quantas vezes for chamada.
• e quando nulo, x != null => x.equals(null) == false.

O primeiro item diz que um objeto deve ser igual a ele mesmo. Num Set, por exemplo, se essa propriedade não estiver presente, um objeto pode ser inserido duas vezes ou não removido corretamente.

Parece lógico mas o desenvolvedor pode cair em armadilhas. Vejamos como não obedecer a segunda propriedade, que diz que dois objetos devem acordar sobre a forma com eles são iguais.

// Broken - violates symmetry!
public final class CaseInsensitiveString {
private final String s;
public CaseInsensitiveString(String s) {
this.s = Objects.requireNonNull(s);
}
// Broken - violates symmetry!
@Override public boolean equals(Object o) {
if (o instanceof CaseInsensitiveString)
return s.equalsIgnoreCase(
((CaseInsensitiveString) o).s);
if (o instanceof String) // One-way interoperability!
return s.equalsIgnoreCase((String) o);
return false;
}
… // Remainder omitted
}

Ao comparar essas duas strings, a segunda propriedade será violada.

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";

Ao comparar cis.equals(s) será retornado true já que ele foi construído para desconsiderar o “case”. O problema ocorre quando s.equals(cis), que retorna false, já que não ignora o “case”. Um “claro caso de violação da simetria”.

Para corrigir, o método equals deve ficar da seguinte forma.

@Override public boolean equals(Object o) {
return o instanceof CaseInsensitiveString &&
((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}

Esqueça a tentativa de lidar com String, o que é chamado no livro de “One-way interoperability!“.

Nesse post falei da primeira e segunda propriedade, sem as quais podem ocorrer inconsistências e causar exceções.

Então até o próximo, no qual continuarei com as outras propriedades.

PS.: a especificação do método equals é encontrada em https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object).

PS.2: nada é trivial.

Effective Java – Item 7 – Elimine referências obsoletas a objetos

Gerenciamento de memória em linguagens com Java, que possuem mecanismo de coleta de lixo, ou garbage collection mechanism, podem evitar problemas de perda de memória, ou “memory leaks“.

As “Memory Leaks” ocorrem quando objetos que já não são utilizados ainda ocupam espaço na memória. Esses objetos estão no Heap e suas variáveis na Stack, no caso do Java.

Não é por haver um mecanismo de coleta de lixo que o programador não deva se preocupar com problemas de memória que um código, até mesmo um simples, pode causar.

Perdas de memória podem gerar uma OutOfMemoryError mas o maior problema é que, na maioria da vezes, ela ocorre de forma silienciosa. E apenas podem ser descobertas com uma inspeção minuciosa do código e com o auxílio de ferramentas de debugging, conhecidas como “heap profiler“.

A classe abaixo armazena um array de objetos, permite o push e o pop de elementos e a cada push, dobra de tamanho.

// Can you spot the "memory leak"?
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}

O problema dela é no método pop. Quando um objeto é retornado e o tamanho diminuído, a stack ainda mantém uma referência obsoleta a esse objeto. Nessa caso, toda referência que estiver fora da “porção ativa” do array serão obsoletos. A porção ativa equivale aos elementos que o índice for menor que o tamanho do array.

Perda de memórias em linguagens como o Java são também conhecidas como retenção não intencionais de objetos, ou “unintentional object retentions“. Esses objetos ficam excluídos do coleta de lixo assim como objetos que ele possa referênciar, e assim por diante.

E a solução? Tornar nulas as referências assim que um objeto se tornar obsoleto. Segue o treco do código com a solução.

public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}

Mas cuidado. Tornar nula referências a objetos deve ser exceção e não regra. E a melhor maneira de eliminar referências obsoletas é definar cada variável num menor escopo possível.

Então quando se deve usar o “null out”? Quais aspectos tornam uma classe suscetível a “memory leaks”? De maneira simples, sempre que houver uma espécie de memória e que seja gerida por ela. No caso da classe Stack, é o array de elementos e seus métodos para incluir e remover. O garbage collector não tem como saber se um elemento está inválido, uma vez que guarda a referência aos objetos e não eles em si. Portanto, isso deve ser feito manualmente pelo programador.

Até o próximo item.

Effective Java – Item 6

Avoid creating unnecessary objects (evite criar objetos desnecessários)

O item do livro diz que é mais apropriado reusar objetos ao invés de criar novos objetos funcionalmente equivalentes cada vez que for necessário. Um objeto pode sempre ser reutilizado se for imutável.

O primeiro exemplo dado é a crição de uma String.

String s = new String("bikini"); // DON'T DO THIS!

Esse código cria uma instância cada vez que é executado e nenhum deles é necessário. O argumento do construtor (“bikini”) já é uma String.

O correto é String s = "bikini";

Em um loop, nesse caso, apenas uma única instância é criado, ao invés de uma para cada vez que for executado.

E se na mesma VM outro objeto contendo “bikini” reusará a instância já criada.

O código abaixo, que verifica se uma String é um numeral romano, e da forma como foi escrito, criará sempre um Pattern para expressão regular, o que é muito caro para a VM.

// Performance can be greatly improved!
static boolean isRomanNumeral(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}

O certo seria criar um objeto imutável que seria reutilizado nas chamadas ao método.

// Reusing expensive object for improved performance
public class RomanNumerals {
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
static boolean isRomanNumeral(String s) {
return ROMAN.matcher(s).matches();
}
}

 Esse código acima rodou 6.5 vezes mais rápido.

Um outro exemplo, que pode levar ao aumento de utilização de recursos, é utilizar o autoboxing, isto é, poder utilizar juntos primitivos e objetos que os encapsulam. Exemplo de long, primitivo, e Long, objeto.

// Hideously slow! Can you spot the object creation?
private static long sum() {
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++)
sum += i;
return sum;
}

O código acima criará 2^31 instâncias de Long desnecessárias. Desta forma, “prefira tipos primitivos a objetos que os encapsulem e tome cuidado nos autoboxing não intencionais”.

Essa parte do livro foi muito interessante pois são situações diárias e que se não forem observadas podem contribuir para diminuir a performance de aplicações.

Segue o link do livro.

 

SpringBoot @Async methods

Today I needed to implement a method to send a notification email after the registration progress. With the actual logic my application was taking too long during the process. So I decide to make the mail sending asynchronous.

First I tried the JMS, the old school Java Message Service API, but I realized that is not that gold, just old.

So after few googling I found a post of Dan Vega, a SpringBoot guru who has courses on Udemy.

With this post I realized: spring make our lives too easy, indeed.

Tow annotations make the method asynchronous, @Async and @EnableAsync.

Here is the post.

Java @Schedule error

I was trying to scheduling a method from a EJB class using the @Schedule annotation of the javax.ejb package.

@Schedule(second=”*/5″, minute=”*”, hour=”*”)
public void listarMsgs()
{
logger.log(Level.INFO, “do something…”);
}

But every time the method was called it  appeared a error like this:

Failed to reinstate timer…

Googling for about some time I figure out that it was a kind bug of the application server, JBoss Wildfly. I’m using the 9 version.

The solution was clear the folder under the standalone/data/timer-service-data that is where the server creates the xml of the schedule job.