Thursday, June 16, 2016

Upgrading from Wildfly 9 + Hibernate 4.3 to Wildfly 10 + Hibernate 5

TL;DR - Exclude Hibernate libraries in POM using <scope>provided</scope> when deploying to Wildfly.

When this project first started several months ago, Wildfly 9 and Hibernate 4.3 was the most current stable releases. Things have changed however, and it's time to move on. The migration provided a couple of learning points, mostly to do with ensuring the project was compatible with the updated versions.

After having Wildfly 10 up and running, I attempted to deploy the WAR file as-is without upgrading to Hibernate 5. The major error that returned from the deployment was about the java.lang.AbstractMethodError similar to this problem. Exactly in SessionFactoryImpl, exactly on line 278. Thinking that there might be a version mismatch (using 4.3 vs 5), I edited the POM to bring all Hibernate libraries up a major version. This was not the case.

 The JPA reference for Wildfly 10 here suggested that Hibernate 5 requires a change to the persistence.xml such that, instead of org.hibernate.ejb.HibernatePersistence
the class name for the <provider> tag should be org.hibernate.jpa.HibernatePersistenceProvider for new deployments. A minor misstep on my part was ignoring the sub-package change of .ejb to .jpa and merely added in "Provider" at the end. That aside, this did not help whatsoever. The documentation goes on to indicate that it's actually possible to leave this value out entirely. So I did.

Next, I even dug into the downloaded zip for Wildfly 10 to check out the libraries they used and made sure to match up what goes into my POM version for version. It eventually caught on in my head that, Wildfly is using its own version of Hibernate to run my package, but encounters the error because I'm providing my own version. I'd previously specified an explicit exclusion in Wildfly for dom4j, but I felt that the complete set of Hibernate 5 library JAR files would be better off being used in conjunction with what Wildfly is familiar with.

The Hibernate dependencies in the POM was modified to have <scope>provided</scope> for this change. And it did the trick! My local Jetty build would have to add these dependencies in, of course.

Thursday, May 19, 2016

Use jMimeMagic instead because Wildfly conflicts with Tika

There was a need to retrieve images from external sites, so after some research, I thought that Tika would do the trick. I had preferred content type detection via magic numbers over file extension only. Unfortunately, the library had a very long list of dependencies. Jetty didn't complain, but the moment I deployed the WAR file on to Wildfly, it encountered a whole bunch of problems, including this. I didn't think the headache was worth the it and sought for an alternative. Google returned this article which had a pretty comprehensive list of libraries. Despite the smaller footprint of mime-util, I decided to go for the more recent jMimeMagic (added TIFF support, last updated 12 Dec 2014, as of today) instead.

Magic parser = new Magic();
MagicMatch match = parser.getMagicMatch(new File("image.jpg"));
System.out.println(match.getMimeType());

That's all there is to using it.

At least Wildfly accepted the new WAR file. We'll have to continue monitoring the situation for this.

Tuesday, February 16, 2016

Spring framework has issues with periods

I didn't know what it was initially, but I found stuff like this, this and this.

The one other thing that stood out to me was when I moused over @RequestMapping in Eclipse and one of the list of arguments was noted as such:
  • @PathVariable annotated parameters (Servlet-only) for access to URI template values (i.e. /hotels/{hotel}). Variable values will be converted to the declared method argument type. By default, the URI template will match against the regular expression [^\.]* (i.e. any character other than period), but this can be changed by specifying another regular expression, like so: /hotels/{hotel:\d+}.
 Simply put, if you URL ends with a period "." then Spring defaults to assuming it could be a file extension, and will strip off anything after the dot and return whatever string preceding it.

My annotation went from

@RequestMapping(value = "/fruits/{fruitName}", method = RequestMethod.GET)

Into inclusion of a simple regex that factors in the period symbol

@RequestMapping(value = "/fruits/{fruitName:.+}", method = RequestMethod.GET)