Tratando Runtime Exceptions em EJB com ExceptionMapper e @ApplicationException

Ao utilizar um ExceptionMapper para tratar exceções em uma aplicação Java EE, é comum que exceções lançadas dentro do contexto de um EJB sejam automaticamente encapsuladas em uma EJBException. Esse comportamento pode dificultar a captura e o tratamento adequado da exceção original.

Para evitar que a exceção seja envolvida por uma EJBException, basta anotá-la com @ApplicationException. Essa anotação informa ao container do EJB que a exceção é de aplicação e não deve ser encapsulada automaticamente.

Exemplo de Código

import jakarta.ejb.ApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

// Definição de uma exceção de aplicação personalizada
@ApplicationException
public class MinhaExcecao extends RuntimeException {
    public MinhaExcecao(String message) {
        super(message);
    }
}

// Implementação do ExceptionMapper para capturar a exceção e gerar uma resposta HTTP adequada
@Provider
public class MinhaExcecaoMapper implements ExceptionMapper<MinhaExcecao> {
    @Override
    public Response toResponse(MinhaExcecao exception) {
        return Response.status(Response.Status.BAD_REQUEST)
                .entity("Erro: " + exception.getMessage())
                .build();
    }
}

// EJB que lança a exceção personalizada
import jakarta.ejb.Stateless;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Stateless
@Path("recurso")
public class MeuRecursoEJB {
    @GET
    public String metodoQueLancaExcecao() {
        throw new MinhaExcecao("Ocorreu um erro específico na lógica de negócio.");
    }
}

Explicação do Código

  1. Criação de uma exceção personalizada (MinhaExcecao): A anotação @ApplicationException evita que ela seja encapsulada em uma EJBException.

  2. Implementação de um ExceptionMapper: Captura MinhaExcecao e retorna uma resposta HTTP 400 (Bad Request).

  3. EJB lançando a exceção: O método metodoQueLancaExcecao() simula um erro que será tratado pelo ExceptionMapper.

Com essa abordagem, garantimos que a exceção seja tratada de maneira controlada e previsível, melhorando a experiência do usuário e a manutenção da aplicação.

All CSS Combinator Selectors

A useful CSS tip for selecting nested elements

This a handful table that shows how to combinator selectors works.

According to the w3schools, a combinator

“is something that explains the relationship between the selectors”

There are four combinators:

  • descendant selector which is represented by a space
  • child selector, with > signal
  • adjacent sibling selector, a + signal
  • general sibling selector, a ~ signal

Above, some examples

Consider the following HTML structure

<body>

<h2>Descendant Selector</h2>

<p>The descendant selector matches all elements that are descendants of a specified element.</p>

<div>
  <p>Paragraph 1 in the div.</p>
  <p>Paragraph 2 in the div.</p>
  <section><p>Paragraph 3 in the div.</p></section>
</div>

<p>Paragraph 4. Not in a div.</p>
<p>Paragraph 5. Not in a div.</p>

</body>

The descendant selector (white space) selects all elements that are descendant of a specified element. So, the next code will paint the three <p> elements inside the div with the yellow color, including the one inside the <section> element.

div p {
  background-color: yellow;
}

The child selector ( > ) selects all elements that are children of a specified element. So, the next code will paint the pair of <p> elements inside the div with the yellow color. But not the <p> inside the <section> because this element is not a child, but a descendant.

div > p {
  background-color: yellow;
}

The adjacent sibling selector ( + ) selects an element that is directly after another specific element. So, the next code will paint only the 4th <p> element, since it is the only directly after a <div>.

div + p {
  background-color: yellow;
}

The general sibling selector ( ~ ) selects all elements that are next siblings of a specified element. So, the next code will paint the last pair of <p> elements.

div ~ p {
  background-color: yellow;
}

CSS is intriguing technology with many cool features that can be applied to enhance a great variety of UI/UX proposes. And is very funny to learn.

I recommend the Advanced CSS and Sass course by Jonas Schmedtmann at Udemy.

Have fun.

Another Flutter build ipa nightmare

Here again, after the annoying 1100 code error when try to run the flutter build ipa command.

Now, the trouble indicates something related to the Provisioning Profile. After two days trying, the solution came after lunch.

Besides the sign in method in XCode was set to automatic, as the flutter pages recommends, the command exits with the following error message:

Provisioning profile doesn’t include signing certificate

So, I took 4 steps to get it done:

  • I decided to upgrade the Flutter version;
  • Run flutter clean;
  • Run flutter build ios;
  • Run flutter build ipa -v –release –dart-define=…

And, like magic, the command generated the ipa file.

Foooooo!!! Hope helps others.

 

Java 11 SDK VsCode Flutter issue

To set a different SDK to a project, add the following property to gradle.properties file:

org.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64/ 

Other approach, that didn’t work for me is include the following property to the settings.json (Ctrl + P):

“java.configuration.runtimes”: [
{
“name”: “JavaSE-1.8”,
“path”: “/usr/lib/jvm/java-8-openjdk-amd64/jre/”
},
{
“name”: “JavaSE-11”,
“path”: “/usr/lib/jvm/java-11-openjdk-amd64/”,
“default”: true
}
]

Nvidia Ubuntu 22.04 driver error (solution)

After a normal boot, the Ubuntu displayed a wrong resolution and an “unknow” device  on display settings.

I searched for the solution for hours and nothing.

So, I decided to try change the recommended driver on “Additional drivers” application to another one with the same number of the version of the GPU. In my case was nvidia-driver-515 that I discovered executing the nvidia-detector command.

Another utility command is the sudo nvidia-bug-report.sh that generates a complete log of the driver, device and so on.

Here is the changing I have done.

 

Flutter build ipa 1100 error

Key

After many tries of executing the flutter build ipa command and receive always the 1100 error saying that “Your session has expired. Please log in.“, I finally done.

There is a right above the last error message, that says:

Try distributing the app in Xcode: “open /Users/user******/Development/Mobile/[[app folder]]/build/ios/archive/Runner.xcarchive”

And that’s it!

The Xcode application starts and ask if I want to automatically sing in. So I marked this option and Xcode ask to log in the Keypass.

After that I tried again to execute the ipa build and everything works fine!

Two lessons: read all error message, always. And don’t give up, never.

UPDATE:

I had to open the Peferences > Account, click on Manage Certificates And + a new Development one cause the old was expired.

After that I tried run the flutter build ipa command an the log says that I must to Build on XCode. So, a prompt ask for my local password many times and build was success.

And them the flutter build occurs.

Ufa!

GOOGLE_APPLICATION_CREDENTIALS alternatives

I couldn’t set GOOGLE_APPLICATION_CREDENTIALS variable on a production server environment that runs a Java war application under a Jboss Wildfly 9 server.

I tried setting at .bashrc, .profile, .bash_profile. I tried even include the variable on standalone.sh. Nothing.

So, I remember that the GoogleCredentials function acepts a FileInputStream that reads the path of the json file.

FirebaseOptions options = FirebaseOptions.builder()
			    .setCredentials(GoogleCredentials.fromStream(new FileInputStream(<<path>>)))
			    .build();

So, after two days, finally, it works.

The solution’s explanation is here.

Android App crashes after flutterfire configure

If your app is crashing on startup when runnging a AVD, you should analyse the logcat from ‘View > Tool Windows > Logcat.

In my case, the crash cause was:

Caused by: java.lang.ClassNotFoundException: Didn't find class "br.com.sidroniolima.medo_e_delirio_app.MainActivity" 

The problem was at AndroidManifest.xml file.

The activity was pointing to a .MainActivity that is not there. It maybe have been occurred when I configure the flutterfire on project.

The Android Plugin upgrade page shows at the 5th step the following:

Android Plugin update page.

(Optional) If you removed MainActivity.java, update the <plugin_name>/example/android/app/src/main/AndroidManifest.xml to use io.flutter.embedding.android.FlutterActivity. For example:

The solution was replace the old block to the new one. As follows.

<activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
<activity
            android:name="io.flutter.embedding.android.FlutterActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">

Pode isso, Cielo? Falha de segurança na API Cielo 3.0

Existe uma falha de segurança na API Java 3.0 da Cielo que expõe dados da resposta de uma transação.

O método parseResponse da calsse AbstractSaleRequest<Request, Response> chama o sysout com a string do corpo da resposta.

A chamada desse método imprime campos como nome do cliente que consta no cartão de crédito, números do cartão com apenas 6 dígitos omitidos, data de vencimento da cartão e ID do pagamento, entre outros.

Em tempos de LGPD, é inadimissível que isso seja exposto.

Abri um chamado pelo suporte da Cielo mas não surtiu efeito. Abri uma issue no github e até agora não responderam. A API parece abandonada e, portanto, deveria, ao menos, ser considerada depreciada.

A solução foi utilizar a API Rest, que não apresenta essa falha.

Segue  o código do método.

/**
	 * Just decode the JSON into a Sale or create the exception chain to be
	 * thrown
	 *
	 * @param statusCode
	 *            The status code of response
	 * @param responseBody
	 *            The response sent by Cielo
	 * @return An instance of Sale or null
	 * @throws CieloRequestException
	 */
	private Response parseResponse(int statusCode, String responseBody, Class<Response> responseClassOf)
			throws CieloRequestException {
		Response response = null;
		Gson gson = new Gson();

		System.out.println(responseBody);

		switch (statusCode) {
		case 200:
		case 201:
			response = gson.fromJson(responseBody, responseClassOf);
			break;
		case 400:
			CieloRequestException exception = null;
			CieloError[] errors = gson.fromJson(responseBody, CieloError[].class);

			for (CieloError error : errors) {
				System.out.printf("%s: %s", "Cielo Error [" + error.getCode() + "]", error.getMessage());

				exception = new CieloRequestException(error.getMessage(), error, exception);
			}

			throw exception;
		case 404:
			throw new CieloRequestException("Not found", new CieloError(404, "Not found"), null);
		default:
			System.out.printf("%s: %s", "Cielo", "Unknown status: " + statusCode);
		}

		return response;
	}

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é.