Skip to main content

Glassfish SecurityManager.checkPermission

Posted by felipegaucho on January 2, 2010 at 2:39 AM PST

After configuring Hudson to run in a Glassfish with security manager enabled I started to have problems in other applications, specially web applications using reflection to access private fields in Java classes. Over the web I noticed a lot of people struggling with the same issue (Seam, GWT, Vaadin, etc). The problem is caused because most of the modern frameworks tries to access Java private fields directly - perhaps motivated by the popularity of type-unsafe languages or just designed for better performance. The frameworks designer expect to have this freedom but the Security Manager imposes strict rules against that. Applications based on these frameworks running on a secure Glassfish will eventually throw an exception like: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)
    at java.lang.SecurityManager.checkPermission(
    [#|2010-01-02T11:28:34.681+0100|WARNING|glassfishv3.0|org.directwebremoting.dwrp.BaseCallMarshaller|_ThreadID=30;_ThreadName=Thread-1;|--Erroring: batchId[1]
     message[java.lang.IllegalAccessError: Class com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection
     can not access a member of class com.kenai.puj.arena.model.entity.PujInstitutionEntity with modifiers "private"]|#]

Here are some alternatives to workaround the problem:

  1. Change the accessibility of classes from fields to methods. You can do that annotating the methods instead of fields, specially for JPA and EJB annotations. In the new book Pro JPA 2, they demonstrate a good practice using methods annotation to facilitate unit testing as well, but this is another topic.
    • Pros: solves the problem without additional container configurations.
    • Cons: goodbye IDE refactorings and auto-completion. I am a fan of auto-completion and usually I have the getters&setters methods generated by the IDE. I can't imagine myself handling getters and setters manually.
  2. Suppress access checks in the security policy of Glassfish. I would say that is the canonical solution, described in the "Issues Related to Security" section of the Glassfish manual.

    • Pros: it follows the Glassfish recommendation and keeps your code and project structure as you want, without alien constraints.
    • Cons: you need to change the Glassfish configuration files what means a risk when you upgrade the server - if you forget to reconfigure the new server, all applications will start to fail (at least it is not a silent killer).

    How to do that?

    1. open the security policy file: glassfishv3/glassfish/domains/domain1/config/server.policy
    2. include the following entry:
    3. grant codeBase "file:${com.sun.aas.installRoot}/domains/domain1/applications/arena-dwr/-" {
          permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

    Don't forget to replace the arena-dwr by the name of your application, and also to check project path if you are not using the default container instance domain1.

More I work with Glassfish more this kind of issue becomes trivial to solve, but perhaps it is hard for new Glassfish adopters to quick fix such problems. A surprising point is the need of hand crafted configurations in local server files. Eventually we could deploy the security policy with the application itself or to include some configuration hints in the sun-web.xml file or other standard configuration file. Perhaps a good suggestion for Glassfish v4.

* I am not suggesting to open the doors allowing web applications to reconfigure the container, but certain flexibility is a desirable feature. Or perhaps a new set of options in the admin GUI for quick fixing the most common configuration problems. And yes, if all framework designers change their mind set, all this problems will never happen, but then you are talking about a brand new world - too much for hope even in the beginning of a new decade :)


Use com.sun.aas.instanceRoot variable instead

You can also use ${com.sun.aas.instanceRoot}/applications/arena-dwr/- to avoid hardcoding domain name in the server.policy.