Hint: SLF4J Konfiguration within an EAR

Hi,

here is an short introduction of how to use slf4j’s logback.xml configuration file within an EAR.

Everybody who uses slf4j (or other Logging Frameworks) knows the following

Problem

When you deliver the configuration file of the logging framework within an WAR works everything as expected and without any problems. But if you try this with an EAR something magically happens, the logging framework can’t find the configuration file. And it uses it’s default behavior – System.out.println often by default -.

Searching this issue with Google shows up several possible solutions, for example exchanging the complete logging mechanism of your application server, or put the configuration file into lib/classes (Glassfish). If you dig a little bit deeper you may also find, that you should put the file into a dedicated jar-archive which is deployed as an ordinary library or that you must put the file into the EAR and extend the classpath, via MANIFEST.MF.

The problems of these possible solutions are, when

  • exchanging the complete server logging
    If you ever update your server, you must ensure, that your modifications weren’t removed and / or were working. If not you must do the manual work again.
  • the configuration file is in lib/classes
    Works only fine – and without manual work -, when the server isn’t used as a cluster node. Otherwise you must put the file after every single restart, creation, .. again manually.
    Additionally you can’t use different log-configuration files for single applications, that includes, that you must edit the single configuration file for every deployed application.
  • using the JAR-Archive 
    Works, but you can’t change the configuration during runtime, because the JAR isn’t exploded.
  • using EAR with Class-Path extension
    Doesn’t work for us

Solution

After doing a little bit research and try-and-error, I could develop this working solution:

  • The configuration file is placed in a folder in the EAR, for example config
  • Every module uses slf4j-API as a direct dependency. If you put this dependency as a common on into the EAR, the configuration file can’t be found.
  • A new module, ‘slf4j’ for example, is introduced and contains, beneath an empty class, an extension of the Class-Path, which points to the folder created above. The empty class is a constraint of the EAR-specification. This module also includes the wished implementation of slf4j.
  • Each module which would like to use logging needs now, a dependency to the ‘slf4j’ module.

As usual you’ll find a minimal example on github.

As a last step a little bit

Background

The cause for this issue depends on the way an EAR-Container is handled by the application servers. The servers uses a kind of sandboxing for the classloaders that are available for an EAR. This means, that the way of providing any kind of resource is affected.

The initial classloader of an EAR-container provides only access to resources, that are available outside of the EAR. That means only standard libraries, libraries provided by the server and everything in the <domain|node>/lib-folder.

A direct impact of this way is, that classes that were provided via the EAR/lib directory have only access to resources outside of the EAR. And here is the reason, why SLF4J can’t find the configuration, when it is located in the EAR-container and the SLF4J libraries were put into the EAR/lib folder.

On the other hand, the modules of an EAR have only, direct, access to resources, that can be referenced from within the EAR.

Tutorial: Using MosKito with CDI

Today I would like to show you how to integrate MosKito into your CDI Application.
I will show you the required dependencies and modifications to some files you need to do before you can use MosKito with CDI.

Preparation

For this tutorial

  • Glassfish version 3.x and
  • Gradle at least in version 1.0

is required.

The example application provides a RESTful webservice, which takes a document (as plain text) and calculates some fancy statistics for it.

Let’s start with the

Dependencies

The MosKito stuff can be retrieved from this repository url http://nexus.anotheria.net/nexus/content/repositories/releases/ .

For MosKito we need moskito-core  and moskito-cdi  at least in version 2.1.4.
The following build-script snippet includes everything we need at the moment.

As you may have noticed I excluded everything from group blowfish. It’s required to do this, otherwise we had some unresolvable dependencies.

RESTful service

Now let us define the RESTful services and the stub for the underlying service. (Notice: I omitted the imports to have less code)

At least we need two data transfer objects, one for the complete statistics and one for a single line

Ok, that was the easy part. But now the big question is, how to enable MosKito for the application. Because MosKito uses interceptors for a CDI-based application we need to activate them via the

beans.xml

The activation can be done very easily by adding the required interceptors to the beans.xml file in the interceptors section.
MosKito provides basically these interceptors:

  • net.anotheria.moskito.integration.cdi.CallInterceptor
    This interceptor produces several runtime statistics.
  • net.anotheria.moskito.integration.cdi.CountInterceptor
    This interceptor is, as the name says, for counting method calls
  • net.anotheria.moskito.integration.cdi.DaoCallInterceptor
    This interceptor extends the CallInterceptor and sets the category to “DAO” by default. It’s used when the @Monitor annotation is qualified with MonitoringCategorySelector.DAO
  • net.anotheria.moskito.integration.cdi.ServiceCallInterceptor
    This interceptor extends the CallInterceptor and sets the category to “SERVICE” by default. It’s used when the @Monitor annotation is qualified with MonitoringCategorySelector.SERVICE. This is default, if you didn’t specify anything.
  • net.anotheria.moskito.integration.cdi.WebCallInterceptor
    This interceptor extends the CallInterceptor and sets the category to “WEB” by default. It’s used when the @Monitor annotation is qualified with MonitoringCategorySelector.WEB

Combining the things together will end in this extend beans.xml

Ok, now let’s put the things together.

Using MosKito

But, what would we like to monitor? ‘uploadAndQueueDocument’ seems to be a good candidate for runtime monitoring the basic stuff like counting the calls and process time per request, whereas ‘getCountingForWord’ and ‘getWordStatistics’ looks like good candidates for counting.

Both types of monitoring can be enabled by using the specific annotations

  • @Monitor for runtime monitoring
  • @Count for simple counting

As you may have noticed I used MonitoringCategorySelector.WEB for @Monitor, because it’s the monitoring from a webservice. 

And that’s it. The configuration and other things could be found here.

The complete example is avaiable on github.

 

Tutorial: How to use JAX-RS and CDI together

Hi,

because it’s relative hard to figure out, how to do it, I would like to show you how to combine JAX-RS and CDI.

Preparation

You need

  • a Glassfish v3.x where we will run this application
  • Gradle at least in version 1.0

Let’s start with a minimal application “The Greeter”.
If you call “<your_host>/GreetMeWithJaxRSAndCDI/rest/greet/<NAME>” it should return “Hi, <NAME>. Today it’s the <DATE>”.

The webservice

That was easy. (I skipped the imports to increase the visibility) Now the Greeting class.

Now let’s add an empty beans.xml and a web.xml with this content

The important thing here is that you need to specify an servlet class which provides an entry point to an implementation of the JAX-RS api. Here I chose Jersey.

Before we can build this “beast” we need to add some dependencies.

So the complete build.gradle will look like this

Ok, let’s build, deploy and call it. If you use a standard glassfish installation, then this link should work http://localhost:8080/GreetMeWithJaxRSAndCDI/rest/greet/peter.

Hmm, doens’t seem to work, or? What’s the problem behind?

The problem here is, that CDI isn’t in place to instantiate the dependency.
Their are two solutions for this problem:

  1.  Let CDI instantiate the dependency, but let Jersey managed it
    This can be achived using @ManagedBean and a Jersey specific annotation.
  2. Let CDI instantiate the dependency and let CDI manage it.
    This can be achieved using @RequestScoped or other CDI specific annotations.

In this example I use the first approach. This means we need to add @ManagedBean to our service.

Ok, let’s do a retry. And violá it works.

Lessons learned

To use JAX-RS and CDI together you need to

  • Specify a servlet which handles the requests (this needs to be done also, when you didn’t want to use CDI)
  • Specify who instatiates and who manages the injected beans:
  • @ManagedBean : CDI instantiates it and Jersey manages the life-cycle
  • @RequestScoped : CDI instantiates and manages the bean

I hope this will help you a little bit.

As usual you’ll find the project on http://github.com/coders-kitchen/GreetMeWithJaxRSAndCDI.

Gradle: Using expand and jQuery

During the last days I started to enable a build-time setup for one of my Spring projects.

One thing I set at build time was the spring.profiles.default  context parameter. For replacing wildcards during build time I added the expand()  closure to the war-task of my Gradle build script.

The problem

This works fine til I wanted to add some access to the webservice the tool provided using jQuery. After adding the jQuery library the build fails with the following message

When starting the build with –stacktrace again, I figured out, that the problem was, that the underlying Groovy implementation expects that, when expand is used after a ‘$’ sign a character or a ‘{‘ follows. jQuery has many ‘$’ signs, so a workaround is required.

My solution

Due to the fact, that expand() works in Gradle on every file on a Copy tasks, for example, and didn’t support single file expansion, I started to investigate how to workaround this issue.

I added two new tasks, one for copying the files, which needs to be replaced and the other for the javascript libraries.

The last things I need to do were

  • changing the webAppDirName to ”$buildDir/webapp”
  • setting the webAppDirName of the jetty task
  • let war and jettyRun depending on the expandForWebApp task

Summarized I did the following changes:

 Conclusion

Even if I think, that the missing possibility for expanding a single file directly is a little drawback withGradle, I’m very happy that Gradle provides me the possibilities to express the things I would like to do directly in the build script.

Gradle – Multi-Modul-Project – Change module path

In Multi-Modul-Projects you have several options to define the directory structure.

One variant, we also use for our projects, is the following: 

The simplest and fastest solution with Gradle is to define the following includes in the settings settings.gradle  file:

This solution has, at least, to drawbacks. One is that you need to define inter-module dependencies in that way project(‘modules:module_k’). The other one is, that you need to use a prefix like this modules:module_k if you would like to start a specific task of one of the submodules.

With Gradle you can change the path for you subprojects:

This has the advantage, that you can directly specify the module for tasks and depdencies.

Info: Projectpaths can only be changed in the settings.gradle file, in the usual build script this property is write only.

JEE and dynamic Dependency Injection

During the last weeks a colleague of mine came to my desk and ask for a solution in JEE6 for the following

Problem

The implementation that should be used for injection via @Inject must be determined during runtime by call parameters of the target bean.

JEE didn’t have, or to be precise I didn’t know a solution for that, a direct solution for that kind of problem.

So my colleague tried this

First solution

He create the required object by his own via new and used setters to manually inject the dependencies, like database connection, … .
However, he quickly realized, that this approach is only sufficient if you have very similar variants of objects (meaning, same dependencies and so on). So if you have an new implementation, which requires a totally different set of dependencies the trouble began.

Another problem with this approach is, that you create / destroy the objects at the JEE container past. So the container isn’t aware of it and you can’t additionally use the lifecycle methods like PostConstruct or PreDestroy.

A possible

Solution

is to use the class Instance with the qualifier @Any. Instance provides a generic container for any implementation of an interface which matches the interfaces and the provided qualifier (here @Any). Additionally this class provides for every available instance the methods isAmbiguous and isUnsatisfied to check if the dependencies are satisfied.

This object can now used to create a factory method which returns the requested object. The cool fact is, that this object is completely JEE aware.
Last but not least a simple

Example

This example is around a simple tax calculator.
This calculator calculates the tax based upon a previous selection of the user. The available variants are “no taxes”, “fixed”, “progressive” and “unbelievable”).

I will demonstrate here only the main components. The complete project is available on GitHub.

The core component is this factory:

As you see here all implemented TaxCalculations are injected via the Instance object. The requested TaxCalculation is determined in the method getTaxCalculationForName via an AnnotationLiteral (see next code example).

The AnnotationLiteral is required to use the select method of Instance. This method returns all instances of the available implementations which matches the conditions:

The qualifier can be realized like this

I hope this little example shows how JEE can be used to easy realize such a mechanism. This approach has also the benefit, that you can easily add new implementations of the TaxCalculation without changing the implementation.

Conclusion

The problem of my colleague had thus be solved in a very elegant matter.
In opposite to my approach, my colleague uses information from the database to determine the dynamic dependency.

I hope that I had shown you that JEE can also be easily used in a dynamic environment. Only a little bit knowledge and “creativity” is required.

Hibernate and java.lang.NoSuchFieldError: TRACE

During the implementation of some integrationstests for a Spring application I faced the problem, that the tests couldn’t be executed due to the following error:

After some investigation I figured out, that Hibernate has a non transitive dependency to Log4J log4j >= 1.2.12 – I use slf4j / logback for logging -.

After I added this dependency  'org.slf4j:slf4j-log4j12:1.6.1'  to my testCompile everything works fine.