Thursday, 28 April 2016

java.lang.IllegalArgumentException: Comparison method violates its general contract!

I got the error message in the title whilst using Flyway to run database scripts at work1.

I find it very satisfying that sorting methods in the JDK can detect if your comparer is not obeying the contract.

There are a lot of errors that cause the contract to be violated according to [2].

Here are the rules in short as described in [3]:
  • sign(compare(x,y)) == -sign(compare(y,x))
  • (compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0 (transitivity)
  • compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z))
Sounds like an excellent starting point for some good JUnit Tests.

References

[1] GitHub - Flyway - Issue 1249
https://github.com/flyway/flyway/issues/1249
[2] StackOverflow - “Comparison method violates its general contract!”
http://stackoverflow.com/questions/8327514/comparison-method-violates-its-general-contract
[3] Oracle Javadoc - Interface Comparator>T>
https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

Thursday, 21 April 2016

Constructors, Javadoc and Inheritance

I recently had the problem that I defined some very good javadoc documentation on a constructor in one of my generic classes that is inherited a lot.

The documentation, however, is never propagated to subclasses, because constructors are not inherited1.

It is too bad that I already have to duplicate Constructors in my subclasses, but now I have to duplicate the documentation as well?

Right now, the best solution I can think of is to add a "@see" link to the appropriate super constructor. Like so:

There is a feature request/bug2 defined to expand the {inheritedDoc} to also work on constructors. But it has not seen any love for a long time.

References

[1] StackOverflow - Why is inheritedDoc not defined on constructors?
http://stackoverflow.com/questions/14848999/why-is-inheriteddoc-not-defined-on-constructors
[2] JDK-4810216 : Allow {@inheritDoc name} for constructors
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4810216

Thursday, 14 April 2016

Java is pass-by-value!

Java is always pass by value, with no exceptions, ever.

From the JLS1:
When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor.

What this means is that the parameter is actually a copy of the value you provided. Hence, Java is always pass by value.

It is the same for the programming language C3.

It is the same for JavaScript4.

Confusion

The following quote from the JLS2 causes a bit of confusion in the discussion:
An object is a class instance or an array.

The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
So, yes, Java does use pointers (to objects). However, these pointers are passed-by-value! This is why you can change the contents of an object but never switch the object for a different object.

References

[1] JLS SE 8 - 8.4.1. Formal Parameters
http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.1
[2] JLS SE 8 - 4.3.1. Objects
https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.3.1
[3] Dennis Kubes - Is C Pass by Value or Reference?
http://denniskubes.com/2012/08/20/is-c-pass-by-value-or-reference/
[4] What's The Pointy - JavaScript does not have "pass by reference"
http://whatsthepointy.blogspot.nl/2013/11/javascript-does-not-have-pass-by.html
JavaDude.com - Java is Pass-by-Value, Dammit!
http://javadude.com/articles/passbyvalue.htm
StackOverflow - Is Java “pass-by-reference” or “pass-by-value”?
http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value

Thursday, 7 April 2016

Security Realms in Glassfish

I recently ran into the problem that the Roles I declared in my application were never assigned to the users I defined, when deployed in my Glassfish server. The log provided me with the following:
2016-03-30T13:13:43.560+0200] [glassfish 5.0] [WARNING] [] [javax.enterprise.system.core.security] [tid: _ThreadID=96 _ThreadName=AutoDeployer] [timeMillis: 1459336423560] [levelValue: 900] [[
No Principals mapped to Role [player].]]
Upon closer inspection, the problem became quite clear.

A more in-depth explanation on how security works in Glassfish can be found in the Java EE 6 Tutorial at [1].

Within a realm (security policy domain) you can define groups and users. Users can be assigned to groups.

Now, there needs to be a mapping between the security as defined in your application, and the security as defined in your application server. There is a bit of a separation between the two, because you need to be able to effortlessly deploy your application to different application servers without having to change your applications security settings.

Even if the realm of the application server happens to be configured differently.
scopesecurity itemsAnnotationsdeployment descriptor
within your applicationroles@DeclareRolls, @RolesAllowedweb.xml
within your application serverusers and groups-glassfish-web.xml

Manual mapping

Manual mapping between groups/users and your applications defined roles, is by using an application server specific deployment descriptor. The one glassfish uses is the WEB-INF/glassfish-web.xml and is included in your application war.

Schematically it looks like the following:

An example of the glassfish-web.xml deployment descriptor:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  <context-root>/myNewWebapp</context-root>
  <security-role-mapping>
    <role-name>admin</role-name>
    <group-name>admin</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>god</role-name>
    <principal-name>root</principal-name>
    <group-name>god</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>player</role-name>
    <group-name>player</group-name>
  </security-role-mapping>
 <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</glassfish-web-app>
In the example above most mappings are between groups and roles. There is one exception, which is the principal (user) "root". He is directly mapped to the "god" role, as he should be.

Automatic mapping

One of the handy features if you wish to use it, is the option for the glassfish server to automatically try to map groups and roles, based on similar names. This can be done in the glassfish administration gui, by going to server-config and selecting security.
It can completely replace the need for a glassfish-web.xml deployment descriptor.

References

[1] Java EE 6 Tutorial - Working with Realms, Users, Groups and Roles
https://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html