Fix Hot Reload of Thymeleaf-Templates In spring-boot:run

The Problem: Hot-Reload Of Thymeleaf-Templates Does Not Work, When The Application Is Run With spring-boot:run

A lot of people seem to have problems with hot reloading of static HTML-ressources when developing a Spring-Boot application that uses Thymeleaf as templateing engine with spring-boot:run.
There are a lot of tips out there, how to fix that problem:

  • The official Hot-Swapping-Guide says, that you just have to add spring.thymeleaf.cache=false in your application-configuration in src/main/resources/application.properties.
  • Some say, that you have to disable caching by setting spring.template.cache=false and spring.thymeleaf.cache=false and/or run the application in debugging mode.
  • Others say, that you have to add a dependency to org.springframework:springloaded to the configuration of the spring-boot-maven-plugin.
  • There is even a bug-report on GitHub, that says, that you have to run the application from your favored IDE.

But none of that fixes worked for me.
Some may work, if I would switch my IDE (I am using Netbeans), but I have not tested that, because I am not willing to switch my beloved IDE because of that issue.

The Solution: Move Your Thymeleaf-Templates Back To src/main/webapp

Fortunatly, I found a simple solution, to fix the issue without all the above stuff.
You simply have to move your Thymeleaf-Templates back to where they belong (IMHO): src/main/webapp and turn of the caching.
It is not necessary to run the application in debugging mode and/or from your IDE, nor is it necessary to add the dependency to springloaded or more configuration-switches.

To move the templates and disable caching, just add the following to your application configuration in src/main/application.properties:

spring.thymeleaf.prefix=/thymeleaf/
spring.thymeleaf.cache=false

Of course, you also have to move your Thymeaf-Templates from src/main/resources/templates/ to src/main/webapp/thymeleaf/.
In my opinion, the templates belong there anyway, in order to have them accessible as normal static HTML(5)-files.
If they are locked away in the classpath you cannot access them, which foils the approach of Thymeleaf, that you can view your templates in a browser as thy are.

Funded by the Europian Union

This article was published in the course of a
resarch-project,
that is funded by the European Union and the federal state Northrhine-Wetphalia.


Europäische Union: Investitionen in unsere Zukunft - Europäischer Fonds für regionale Entwicklung
EFRE.NRW 2014-2020: Invesitionen in Wachstum und Beschäftigung

java.lang.Exception: Method XZY should have no parameters

Did you ever stumbled across the following error during developing test-cases with JUnit and JMockit?

java.lang.Exception: Method XZY should have no parameters

Here is the quick and easy fix for it:
Fix the ordering of the dependencies in your pom.xml.
The dependency for JMockit has to come first!

Funded by the Europian Union

This article was published in the course of a
resarch-project,
that is funded by the European Union and the federal state Northrhine-Wetphalia.


Europäische Union: Investitionen in unsere Zukunft - Europäischer Fonds für regionale Entwicklung
EFRE.NRW 2014-2020: Invesitionen in Wachstum und Beschäftigung

Integrating A Maven-Backend- With A Nodjs/Grunt-Fronted-Project

Frontend-Development With Nodjs and Grunt

As I already wrote in a previous article, frontend-development is mostly done with Nodjs and Grunt nowadays.
As I am planing to base the frontend of my next Spring-Application on Bootstrap, I was looking for a way to integrate my backend, which is build using Spring and Thymeleaf and managed with Maven, with a frontend, which is based on Bootstrap and, hence, build with Nodjs and Grunt.

Integrate The Frontend-Build Into The Maven-Build-Process

As I found out, one can integrate a npm-based build into a maven project with the help of the frontend-maven-plugin.
This plugin automates the managment of Nodjs and its libraries and ensures that the version of Node and NPM being run is the same in every build environment.
As a backend-developer, you do not have to install any of the frontend-tools manualy.
Because of that, this plugin is ideal to integrate a separately developed frontend into a maven-build, without bothering the backend-developers with details of the frontend-build-process.

Seperate The Frontend-Project From The Maven-Based Backend-Project

The drawback with this approach is, that the backend- and the frontend-project are tightly coupled.
You can configure the frontend-maven-plugin to use a separate subdirectory as working-directory (for example src/main/frontend) and utilize this to separate the frontend-project in its own repository (for example by using the submodule-functions of git).
But the grunt-tasks, that you call in the frontend-project through the frontend-maven-plugin, must be defined in that project.

Since I am planing to integrate a ‐ slightly modified ‐ version of Bootstrap as frontend into my project, that would mean that I have to mess around with the configuration of the Bootstrap-project a lot.
But that is not a very good idea, because it hinders upgrades of the Bootstrap-base, because merge-conflicts became more and more likely.

So, I decided to program a special Gruntfile.js, that resides in the base-folder of my Maven-project and lets me redefine and call tasks of a separated frontend-project in a subdirectory.

Redefine And Call Tasks Of An Included Gruntfile From A Sub-Project

As it turned out, there are several npm-plugins for managing and building sub-projects (like grunt-subgrunt or grunt-recurse) or including existing Gruntfiles from sub-projects (like grunt-load-gruntfile), but none of them lets you redefine tasks of the subproject before calling them.

I programmed a simple Gruntfile, that lets you do exactly this:


module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-newer');

  grunt.registerTask('frontend','Build HTML & CSS for Frontend', function() {
    var
    done = this.async(),
    path = './src/main/frontend';

    grunt.util.spawn({
      cmd: 'npm',
      args: ['install'],
      opts: { cwd: path, stdio: 'inherit' }
    }, function (err, result, code) {
      if (err || code > 0) {
        grunt.fail.warn('Failed installing node modules in "' + path + '".');
      }
      else {
        grunt.log.ok('Installed node modules in "' + path + '".');
      }

      process.chdir(path);
      require(path + '/Gruntfile.js')(grunt);
      grunt.task.run('newer:copy');
      grunt.task.run('newer:less');
      grunt.task.run('newer:svgstore');

      done();
    });
  });


  grunt.registerTask('default', [ 'frontend' ]);

};

This Gruntfile loads the npm-taks grunt-newer.
Then, it registers a grunt-task called frontend, that loads the dependencies of the specified sub-project, read in its Gruntfile and runs redefined versions of the tasks copy, less and svgstore, which are defined in the sub-project.
The sub-project itself does not register grunt-newer itself.
This is done in this parent-project, to demonstrate how to register additional grunt-plugins and redefine tasks of the sub-project without touching it at all.

The separated frontend-project can be used by the frontend-team to develop the temlates, needed by the backend-developers, without any knowledge of the maven-project.
The frontend-project is then included into the backend, which is managed by maven, and can be used by the backend-developers without the need to know anything about the techniques that were used to develop the templates.

The whole example can be browsed at juplo.de/gitweb or cloned with:


git clone http://juplo.de/git/examples/maven-grunt-integration

Be sure to checkout the tag 2.0.0 for the corresponding version after the cloning, in case i add more commits to demonstrate other stuff.
Also, you have to init and clone the submodule after checkout:


git submodule init
git submodule update

If you run mvn jetty:run, you will notice, that the frontend-maven-plugin will automatically download Nodejs into a the folder node of the parent-project.
Afterwards, the dependencies of the parent-project are downloaded in the folder node_modules of the parent-project and the dpendencies of the sub-project are downloaded in the folder src/main/frontend/node_modules and the sub-project is build automatically in the folder src/main/frontend/dist, which is included into the directory-tree that is served by the jetty-maven-plugin.

The sub-project is fully usable standalone to drive the development of the frontend separately.
You can read more about it in this previous article.

Conclusion

In this article, I showed how to integrate a separately developed frontend-project into a backend-project managed by Maven.
This enables you to separate the development of the layout and the logic of a classic ROCA-project nearly totally.

Configure pac4j for a Social-Login along with a Spring-Security based Form-Login

The Problem – What will be explained

If you just want to enable your spring-based webapplication to let users log in with their social accounts, without changing anything else, pac4j should be your first choice.
But the provided example only shows, how to define all authentication mechanisms via pac4j.
If you already have set up your log-in via spring-security, you have to reconfigure it with the appropriate pac4j-mechanism.
That is a lot of unnecessary work, if you just want to supplement the already configured log in with the additionally possibility, to log in via a social provider.

In this short article, I will show you, how to set that up along with the normal form-based login of Spring-Security.
I will show this for a Login via Facabook along the Form-Login of Spring-Security.
The method should work as well for other social logins, that are supported by spring-security-pac4j, along other login-mechanisms provided by spring-security out-of-the-box.

In this article I will not explain, how to store the user-profile-data, that was retrieved during the social login.
Also, if you need more social interaction, than just a login and access to the default data in the user-profile you probably need spring-social. How to combine spring-social with spring-security for that purpose, is explained in this nice article about how to add social sign in to a spring-mvc weba-pplication.

Adding the Required Maven-Artifacts

In order to use spring-security-pac4j to login to facebook, you need the following maven-artifacts:


<dependency>
  <groupId>org.pac4j</groupId>
  <artifactId>spring-security-pac4j</artifactId>
  <version>1.2.5</version>
</dependency>
<dependency>
  <groupId>org.pac4j</groupId>
  <artifactId>pac4j-http</artifactId>
  <version>1.7.1</version>
</dependency>
<dependency>
  <groupId>org.pac4j</groupId>
  <artifactId>pac4j-oauth</artifactId>
  <version>1.7.1</version>
</dependency>

Configuration of Spring-Security (Without Social Login via pac4j)

This is a bare minimal configuration to get the form-login via Spring-Security working:


<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
    ">

  <security:http use-expressions="true">
    <security:intercept-url pattern="/**" access="permitAll"/>
    <security:intercept-url pattern="/home.html" access="isAuthenticated()"/>
    <security:form-login login-page="/login.html" authentication-failure-url="/login.html?failure"/>
    <security:logout/>
    <security:remember-me/>
  </security:http>

  <security:authentication-manager>
    <security:authentication-provider>
      <security:user-service>
  	<security:user name="user" password="user" authorities="ROLE_USER" />
      </security:user-service>
    </security:authentication-provider>
  </security:authentication-manager>

</beans>

The http defines, that the access to the url /home.html is restriced and must be authenticated via a form-login on url /login.html.
The authentication-manager defines an in-memory authentication-provider for testing purposes with just one user (username: user, password: user).
For more details, see the documentation of spring-security.

Enabling pac4j via spring-security-pac4j alongside

To enable pac4j alongside, you have to add/change the following:


<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
    ">

  <security:http use-expressions="true">
    <security:custom-filter position="OPENID_FILTER" ref="clientFilter"/>
    <security:intercept-url pattern="/**" access="permitAll()"/>
    <security:intercept-url pattern="/home.html" access="isAuthenticated()"/>
    <security:form-login login-page="/login.html" authentication-failure-url="/login.html?failure"/>
    <security:logout/>
  </security:http>

  <security:authentication-manager alias="authenticationManager">
    <security:authentication-provider>
      <security:user-service>
  	<security:user name="user" password="user" authorities="ROLE_USER" />
      </security:user-service>
    </security:authentication-provider>
    <security:authentication-provider ref="clientProvider"/>
  </security:authentication-manager>

  <!-- entry points -->
  <bean id="facebookEntryPoint" class="org.pac4j.springframework.security.web.ClientAuthenticationEntryPoint">
    <property name="client" ref="facebookClient"/>
  </bean>

  <!-- client definitions -->
  <bean id="facebookClient" class="org.pac4j.oauth.client.FacebookClient">
    <property name="key" value="145278422258960"/>
    <property name="secret" value="be21409ba8f39b5dae2a7de525484da8"/>
  </bean>
  <bean id="clients" class="org.pac4j.core.client.Clients">
    <property name="callbackUrl" value="http://localhost:8080/callback"/>
    <property name="clients">
      <list>
        <ref bean="facebookClient"/>
      </list>
    </property>
  </bean>

  <!-- common to all clients -->
  <bean id="clientFilter" class="org.pac4j.springframework.security.web.ClientAuthenticationFilter">
    <constructor-arg value="/callback"/>
    <property name="clients" ref="clients"/>
    <property name="sessionAuthenticationStrategy" ref="sas"/>
    <property name="authenticationManager" ref="authenticationManager"/>
  </bean>
  <bean id="clientProvider" class="org.pac4j.springframework.security.authentication.ClientAuthenticationProvider">
    <property name="clients" ref="clients"/>
  </bean>
  <bean id="httpSessionRequestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"/>
  <bean id="sas" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>

</beans>

In short:

  1. You have to add an additional filter in http.
    I added this filter on position OPENID_FILTER, because pac4j introduces a unified way to handle OpenID and OAuth and so on.
    If you are using the OpenID-mechanism of spring-security, you have to use another position in the filter-chain (for example CAS_FILTER) or reconfigure OpenID to use the pac4j-mechanism, which should be fairly straight-forward.

    The new Filter has the ID clientFilter and needs a reference to the authenticationManager.
    Also, the callback-URL (here: /callback) must be mapped to your web-application!
  2. You have to add an additional authentication-provider to the authentication-manager, that references your newly defined pac4j-ClientProvider (clientProvider).
  3. You have to configure your entry-points as pac4j-clients.
    In the example above, only one pac4j-client, that authenticats the user via Facebook, is configured.
    You easily can add more clients: just copy the definitions from the spring-security-pac4j example.

That should be all, that is necessary, to enable a Facebook-Login in your Spring-Security web-application.

Do Not Forget To Use Your Own APP-ID!

The App-ID 145278422258960 and the accompanying secret be21409ba8f39b5dae2a7de525484da8 were taken from the spring-security-pac4j example for simplicity.
That works for a first test-run on localhost.
But you have to replace that with your own App-ID and -scecret, that you have to generate using your App Dashboard on Facebook!

More to come…

This short article does not show, how to save the retrieved user-profiles in your user-database, if you need that.
I hope, I will write a follow-up on that soon.
In short:
pac4j creates a Spring-Security UserDetails-Instance for every user, that was authenticated against it.
You can use this, to access the data in the retrieved user-profile (for example to write out the name of the user in a greeting or contact him via e-mail).

hibernate4-maven-plugin 1.1.0 released!

Today we released the version 1.1.0 of hibernate4-maven-plugin to Central!

The main work in this release were modification to the process of configuration-gathering.
The plugin now also is looking for a hibernate.cfg.xml on the classpath or a persistence-unit specified in a META-INF/persistence.xml.

With this enhancement, the plugin is now able to deal with all examples from the official
Hibernate Getting Started Guide.

All configuration infos found are merged together with the same default precedences applied by hibernate.
So, the overall order, in which possible configuration-sources are checked is now (each later source might overwrite settings of a previous source):

  1. hibernate.properties
  2. hibernate.cfg.xml
  3. persistence.xml
  4. maven properties
  5. plugin configuration

Because the possible new configuration-sources might change the expected behavior of the plugin, we lifted the version to 1.1.

This release also fixes a bug, that occured on some platforms, if the path to the project includes one or more space characters.

Release notes:


commit 94e6b2e93fe107e75c9d20aa1eb3126e78a5ed0a
Author: Kai Moritz
Date: Sat May 16 14:14:44 2015 +0200

Added script to check outcome of the hibernate-tutorials

commit b3f8db2fdd9eddbaac002f94068dd1b4e6aef9a8
Author: Kai Moritz
Date: Tue May 5 12:43:15 2015 +0200

Configured hibernate-tutorials to use the plugin

commit 4b6fc12d443b0594310e5922e6ad763891d5d8fe
Author: Kai Moritz
Date: Tue May 5 12:21:39 2015 +0200

Fixed the settings in the pom's of the tutorials

commit 70bd20689badc18bed866b3847565e1278433503
Author: Kai Moritz
Date: Tue May 5 11:49:30 2015 +0200

Added tutorials of the hibernate-release 4.3.9.Final as integration-tests

commit 7e3e9b90d61b077e48b59fc0eb63059886c68cf5
Author: Kai Moritz
Date: Sat May 16 11:04:36 2015 +0200

JPA-jdbc-properties are used, if appropriate hibernate-properties are missing

commit c573877a186bec734915fdb3658db312e66a9083
Author: Kai Moritz
Date: Thu May 14 23:43:13 2015 +0200

Hibernate configuration is gathered from class-path by default

commit 2a85cb05542795f9cd2eed448f212f92842a85e8
Author: Kai Moritz
Date: Wed May 13 09:44:18 2015 +0200

Found no way to check, that mapped classes were found

commit 038ccf9c60be6c77e2ba9c2d2a2a0d261ce02ccb
Author: Kai Moritz
Date: Tue May 12 22:13:23 2015 +0200

Upgraded scannotation from 1.0.3 to 1.0.4

This fixes the bug that occures on some platforms, if the path contains a
space. Created a fork of scannotation to bring the latest bug-fixes from SVN
to maven central...

commit c43094689043d7da04df6ca55529d0f0c089d820
Author: Kai Moritz
Date: Sun May 10 19:06:27 2015 +0200

Added javadoc-jar to deployed artifact

commit 524cb8c971de87c21d0d9f0e04edf6bd30f77acc
Author: Kai Moritz
Date: Sat May 9 23:48:39 2015 +0200

Be sure to relase all resources (closing db-connections!)

commit 1e5cca792c49d60e20d7355eb97b13d591d80af6
Author: Kai Moritz
Date: Sat May 9 22:07:31 2015 +0200

Settings in a hibernate.cfg.xml are read

commit 9156c5f6414b676d34eb0c934e70604ba822d09a
Author: Kai Moritz
Date: Tue May 5 23:42:40 2015 +0200

Catched NPE, if hibernate-dialect is not set

commit 62859b260a47e70870e795304756bba2750392e3
Author: Kai Moritz
Date: Sun May 3 18:53:24 2015 +0200

Upgraded oss-type, maven-plugin-api and build/report-plugins

commit c1b3b60be4ad2c5c78cb1e3706019dfceb390f89
Author: Kai Moritz
Date: Sun May 3 18:53:04 2015 +0200

Upgraded hibernate to 4.3.9.Final

commit 038ccf9c60be6c77e2ba9c2d2a2a0d261ce02ccb
Author: Kai Moritz
Date: Tue May 12 22:13:23 2015 +0200

Upgraded scannotation from 1.0.3 to 1.0.4

This fixes the bug that occures on some platforms, if the path contains a
space. Created a fork of scannotation to bring the latest bug-fixes from SVN
to maven central...

commit c43094689043d7da04df6ca55529d0f0c089d820
Author: Kai Moritz
Date: Sun May 10 19:06:27 2015 +0200

Added javadoc-jar to deployed artifact

commit 524cb8c971de87c21d0d9f0e04edf6bd30f77acc
Author: Kai Moritz
Date: Sat May 9 23:48:39 2015 +0200

Be sure to relase all resources (closing db-connections!)

commit 1e5cca792c49d60e20d7355eb97b13d591d80af6
Author: Kai Moritz
Date: Sat May 9 22:07:31 2015 +0200

Settings in a hibernate.cfg.xml are read

commit 9156c5f6414b676d34eb0c934e70604ba822d09a
Author: Kai Moritz
Date: Tue May 5 23:42:40 2015 +0200

Catched NPE, if hibernate-dialect is not set

commit 62859b260a47e70870e795304756bba2750392e3
Author: Kai Moritz
Date: Sun May 3 18:53:24 2015 +0200

Upgraded oss-type, maven-plugin-api and build/report-plugins

commit c1b3b60be4ad2c5c78cb1e3706019dfceb390f89
Author: Kai Moritz
Date: Sun May 3 18:53:04 2015 +0200

Upgraded hibernate to 4.3.9.Final

commit 038ccf9c60be6c77e2ba9c2d2a2a0d261ce02ccb
Author: Kai Moritz
Date: Tue May 12 22:13:23 2015 +0200

Upgraded scannotation from 1.0.3 to 1.0.4

This fixes the bug that occures on some platforms, if the path contains a
space. Created a fork of scannotation to bring the latest bug-fixes from SVN
to maven central...

commit c43094689043d7da04df6ca55529d0f0c089d820
Author: Kai Moritz
Date: Sun May 10 19:06:27 2015 +0200

Added javadoc-jar to deployed artifact

commit 524cb8c971de87c21d0d9f0e04edf6bd30f77acc
Author: Kai Moritz
Date: Sat May 9 23:48:39 2015 +0200

Be sure to relase all resources (closing db-connections!)

commit 1e5cca792c49d60e20d7355eb97b13d591d80af6
Author: Kai Moritz
Date: Sat May 9 22:07:31 2015 +0200

Settings in a hibernate.cfg.xml are read

commit 9156c5f6414b676d34eb0c934e70604ba822d09a
Author: Kai Moritz
Date: Tue May 5 23:42:40 2015 +0200

Catched NPE, if hibernate-dialect is not set

commit 62859b260a47e70870e795304756bba2750392e3
Author: Kai Moritz
Date: Sun May 3 18:53:24 2015 +0200

Upgraded oss-type, maven-plugin-api and build/report-plugins

commit c1b3b60be4ad2c5c78cb1e3706019dfceb390f89
Author: Kai Moritz
Date: Sun May 3 18:53:04 2015 +0200

Upgraded hibernate to 4.3.9.Final

commit 248ff3220acc8a2c11281959a1496adc024dd4df
Author: Kai Moritz
Date: Sun May 3 18:09:12 2015 +0200

Renamed nex release to 1.1.0

commit 2031d4cfdb8b2d16e4f2c7bbb5c03a15b4f64b21
Author: Kai Moritz
Date: Sun May 3 16:48:43 2015 +0200

Generation of tables and rows for auditing is now default

commit 42465d2a5e4a5adc44fbaf79104ce8cc25ecd8fd
Author: Kai Moritz
Date: Sun May 3 16:20:58 2015 +0200

Fixed mojo to scan for properties in persistence.xml

commit d5a4326bf1fe2045a7b2183cfd3d8fdb30fcb406
Author: Kai Moritz
Date: Sun May 3 14:51:12 2015 +0200

Added an integration-test, that depends on properties from a persistence.xml

commit 5da1114d419ae10f94a83ad56cea9856a39f00b6
Author: Kai Moritz
Date: Sun May 3 14:51:46 2015 +0200

Switched to usage of a ServiceRegistry

commit fed9fc9e4e053c8b61895e78d1fbe045fadf7348
Author: Kai Moritz
Date: Sun May 3 11:42:54 2015 +0200

Integration-Test for envers really generates the SQL

commit fee05864d61145a06ee870fbffd3bff1e95af08c
Author: Kai Moritz
Date: Sun Mar 15 16:56:22 2015 +0100

Extended integration-test "hib-test" to check for package-level annotations

commit 7518f2a7e8a3d900c194dbe61609efa34ef047bd
Author: Kai Moritz
Date: Sun Mar 15 15:42:01 2015 +0100

Added support for m2e

Thanks to Andreas Khutz

Logging Request- and Response-Data From Requets Made Through RestTemplate

Logging request- and response-data for requests made through Spring’s RestTemplate is quite easy, if you know, what to do.
But it is rather hard, if you have no clue where to start.
Hence, I want to give you some hints in this post.

In its default configuration, the RestTemplate uses the HttpClient of the Apache HttpComponents package.
You can verify this and the used version with the mvn-command


mvn dependency:tree

To enable for example logging of the HTTP-Headers send and received, you then simply can add the following to your logging configuration:


<logger name="org.apache.http.headers">
  <level value="debug"/>
</logger>

Possible Pitfalls

If that does not work, you should check, which version of the Apache HttpComponents your project actually is using, because the name of the logger has changed between version 3.x and 4.x.
Another common cause of problems is, that the Apache HttpComponets uses Apache Commons Logging.
If the jar for that library is missing, or if your project uses another logging library, the messages might get lost because of that.

hibernate4-maven-plugin 1.0.5 released!

Today we released the version 1.0.5 of hibernate4-maven-plugin to Central!

This release mainly fixes a NullPointerException-bug, that was introduced in 1.0.4.
The NPE was triggered, if a hibernate.properties-file is present and the dialect is specified in that file and not in the plugin configuration.
Thanks to Paulo Pires and and everflux, for pointing me at that bug.

But there are also some minor improvements to talk about:

  • Package level annotations are now supported (Thanks to Joachim Van der Auwera for that)
  • Hibernate Core was upgraded to 4.3.7.Final
  • Hibernate Envers was upgraded to 4.3.7.Final
  • Hibernate Validator was upgrades to 5.1.3.Final

The upgrade of Hibernate Validator is a big step, because 5.x supports Bean Validation 1.1 (JSR 349).
See the FAQ of hibernate-validator for more details on this.

Because Hibernate Validator 5 requires the Unified Expression Language (EL) in version 2.2 or later, a dependency to javax.el-api:3.0.0 was added.
That does the trick for the integration-tests included in the source code of the plugin.
But, because I am not using Hibernate Validator in any of my own projects, at the moment, the upgrade may rise some backward compatibility errors, that I am not aware of.
If you stumble across any problems, please let me know!

Release notes:


commit ec30af2068f2d12a9acf65474ca1a4cdc1aa7122
Author: Kai Moritz
Date: Tue Nov 11 15:28:12 2014 +0100

[maven-release-plugin] prepare for next development iteration

commit 18840e3c775584744199d8323eb681b73b98e9c4
Author: Kai Moritz
Date: Tue Nov 11 15:27:57 2014 +0100

[maven-release-plugin] prepare release hibernate4-maven-plugin-1.0.5

commit b95416ef16bbaafecb3d40888fe97e70cdd75c77
Author: Kai Moritz
Date: Tue Nov 11 15:10:32 2014 +0100

Upgraded hibernate-validator from 4.3.2.Final to 5.1.3.Final

Hibernate Validator 5 requires the Unified Expression Language (EL) in
version 2.2 or later. Therefore, a dependency to javax.el-api:3.0.0 was
added. (Without that, the compilation of some integration-tests fails!)

commit ad979a8a82a7701a891a59a183ea4be66672145b
Author: Kai Moritz
Date: Tue Nov 11 14:32:42 2014 +0100

Upgraded hibernate-core, hibernate-envers, hibernate-validator and maven-core

* Upgraded hibernate-core from 4.3.1.Final to 4.3.7.Final
* Upgraded hibernate-envers from 4.3.1.Final to 4.3.7.Final
* Upgraded hibernate-validator from 4.3.1.Final to 4.3.2.Final
* Upgraded maven-core from 3.2.1 to 3.2.3

commit 347236c3cea0f204cefd860c605d9f086e674e8b
Author: Kai Moritz
Date: Tue Nov 11 14:29:23 2014 +0100

Added FAQ-entry for problem with whitespaces in the path under Windows

commit 473c3ef285c19e0f0b85643b67bbd77e06c0b926
Author: Kai Moritz
Date: Tue Oct 28 23:37:45 2014 +0100

Explained how to suppress dependency-scanning in documentation

Also added a test-case to be sure, that dependency-scanning is skipped, if
the parameter "dependencyScanning" is set to "none".

commit 74c0dd783b84c90e116f3e7f1c8d6109845ba71f
Author: Kai Moritz
Date: Mon Oct 27 09:04:48 2014 +0100

Fixed NullPointerException, when dialect is specified in properties-file

Also added an integration test-case, that proofed, that the error was
solved.

commit d27f7af23c82167e873ce143e50ce9d9a65f5e61
Author: Kai Moritz
Date: Sun Oct 26 11:16:00 2014 +0100

Renamed an integration-test to test for whitespaces in the filename

commit 426d18e689b89f33bf71601becfa465a00067b10
Author: Kai Moritz
Date: Sat Oct 25 17:29:41 2014 +0200

Added patch by Joachim Van der Auwera to support package level annotations

commit 3a3aeaabdb1841faf5e1bf8d220230597fb22931
Author: Kai Moritz
Date: Sat Oct 25 16:52:34 2014 +0200

Integrated integration test provided by Claus Graf (clausgraf@gmail.com)

commit 3dd832edbd50b1499ea6d53e4bcd0ad4c79640ed
Author: Kai Moritz
Date: Mon Jun 2 10:31:13 2014 +0200

[maven-release-plugin] prepare for next development iteration

Running aspectj-maven-plugin with the current Version 1.8.1 of AspectJ

Lately, I stumbled over a syntactically valid class, that can not be compiled by the aspectj-maven-plugin, even so it is a valid Java-7.0 class.

Using the current version (Version 1.8.1) of AspectJ solves this issue.
But unfortunatly, there is no new version of the aspectj-maven-plugin available, that uses this new version of AspectJ.
The last version of the aspectj-maven-plugin was released to Maven Central on December the 4th 2013 and this versions is bundeled with the version 1.7.2 of AspectJ.

The simple solution is, to bring the aspectj-maven-plugin to use the current version of AspectJ.
This can be done, by overwriting its dependency to the bundled aspectj.
This definition of the plugin does the trick:


<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>1.6</version>
  <configuration>
    <complianceLevel>1.7</complianceLevel>
    <aspectLibraries>
      <aspectLibrary>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
      </aspectLibrary>
    </aspectLibraries>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjtools</artifactId>
      <version>1.8.1</version>
    </dependency>
  </dependencies>
</plugin>

The crucial part is the explicit dependency, the rest depends on your project and might have to be adjusted accordingly:


  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjtools</artifactId>
      <version>1.8.1</version>
    </dependency>
  </dependencies>

I hope, that helps, folks!

aspectj-maven-plugin can not compile valid Java-7.0-Code

I stumbled over a valid construction, that can not be compiled by the aspectj-maven-plugin:


class Outer
{
  void outer(Inner inner)
  {
  }

  class Inner
  {
    Outer outer;

    void inner()
    {
      outer.outer(this);
    }
  }
}

This code might look very useless.
Originally, it Inner was a Thread, that wants to signal its enclosing class, that it has finished some work.
I just striped down all other code, that was not needed, to trigger the error.

If you put the class Outer in a maven-project and configure the aspectj-maven-plugin to weave this class with compliance-level 1.6, you will get the following error:


[ERROR] Failed to execute goal org.codehaus.mojo:aspectj-maven-plugin:1.6:compile (default-cli) on project shouter: Compiler errors:
[ERROR] error at outer.inner(this);
[ERROR] 
[ERROR] /home/kai/juplo/shouter/src/main/java/Outer.java:16:0::0 The method inner(Outer.Inner) is undefined for the type Outer
[ERROR] error at queue.done(this, System.currentTimeMillis() - start);
[ERROR] 

The normal compilation works, because the class is syntactically correct Java-7.0-Code.
But the AspectJ-Compiler (Version 1.7.4) bundeled with the aspectj-maven-pluign will fail!

Fortunately, I found out, how to use the aspectj-maven-plugin with AspectJ 1.8.3.

So, if you have a similar problem, read on…

Changes in log4j.properties are ignored, when running sl4fj under Tomcat

Lately, I run into this very subtle bug:
my logs were all visible, like intended and configured in log4j.properties (or log4j.xml), when I fired up my web-application in development-mode under Jetty with mvn jetty:run.
But if I installed the application on the production-server, which uses a Tomcat 7 servlet-container, no special logger-configuration where picked up from my configuration-file.
But – very strange – my configuration-file was not ignored completely.
The appender-configuration and the log-level from the root-logger where picked up from my configuration-file.
Only all special logger-configuration were ignored.

Erroneous logging-configuration

Here is my configuration, as it was when I run into the problem:

  • Logging was done with slf4j
  • Logs were written by log4j with the help of slf4j-log4j12
  • Because I was using some legacy libraries, that were using other logging-frameworks, I had to include some bridges to be able to include the log-messages, that were logged through this frameworks in my log-files.
    I used: jcl-over-slf4j and log4j-over-slf4j.

Do not use sl4fj-log4j and log4j-over-slf4j together!

As said before:
All worked as expected while developing under Jetty and in production under Tomcat, only special logger-confiugrations where ignored.

Because of that, it took me quiet a while and a lot of reading, to figure out, that this was not a configuration-issue, but a clash of libraries.
The cause of this strange behaviour were the fact, that one must not use the log4j-binding slf4j-log4j12 and the log4j-bridge log4j-over-slf4j together.

This fact is quiet logically, because it should push all your logging-statements into an endless loop, where they are handed back and forth between sl4fj and log4j as stated in the sl4fj-documentation here.
But if you see all your log-messages in development and in production only the configuration behaves strangley, this mistake is realy hard to figure out!
So, I hope I can save you some time by dragging your attention to this.

The solution

Only the cause is hard to find.
The solution is very simple:
Just switch from log4j to logback.

There are some more good reasons, why you should do this anyway, over which you can learn more here.