users@glassfish.java.net

Re: EE/EJB spec. conflict regarding classloading?

From: Marina Vatkina <marina.vatkina_at_oracle.com>
Date: Wed, 09 Nov 2011 10:53:03 -0800

EJB 3.2 will have this restriction removed.

-marina

Laird Nelson wrote:
> Hello; I've been having a very interesting conversation with
> Jean-Louis Monteiro over on Twitter (http://twitter.com/chuggid). It
> centers on the interaction between the EJB and Java EE 6
> specifications in the area of classloading and what the two
> specifications permit and deny. Since Glassfish is the reference
> implementation for both specifications I wanted to ask some of the
> questions here.
>
> Briefly: I want to read a resource on the classpath from library code
> used by an EJB's business method. May I?
>
> The EJB specification as everyone knows goes to great length to
> prohibit file access. I understand that. Such IO is not
> transactional or "cloud friendly". But it seems to tread very
> carefully in the area of ClassLoader#getResource(String). Despite
> being very clear about what is prohibited, it does not single out this
> very common operation as one that is prohibited.
>
> Section 21.2.2 says, among other things, this:
>
> * An enterprise bean must not use the java.io <http://java.io>
> package to attempt to access files and directories in the
> file system.
>
> (Bullet point #4, numbered starting with 1.)
>
> That's fine; I'm not interested in using java.io <http://java.io> to
> access files and directories.
>
> Then it says this:
>
> * The enterprise bean must not attempt to directly read or
> write a file descriptor.
>
> (Bullet point #10.)
>
> That's fine; I'm not doing that either.
>
> But it also says this:
>
> * The enterprise bean must not attempt to create a class
> loader; /obtain the current class loader/; set the context
> class loader; set security manager; create a new security
> manager; stop the JVM; or change the input, output, and
> error streams.
>
> Note the "obtain the current class loader" bit. I am assuming that
> the "current class loader" is /not/ the ClassLoader returned by
> Thread.currentThread().getContextClassLoader(), but is, instead, the
> ClassLoader that is returned by this.getClass().getClassLoader(). In
> any event this seemed kind of surprising. I would appreciate
> clarification here. May I really not call getClass().getClassLoader()
> from within an EJB?
>
> Then I read the EE 6 specification, section EE.6.2.4.7:
>
> This specification requires that Java EE containers provide a per
> thread context class loader for the use of system or library
> classes in dynamically loading classes provided by the
> application. The EJB specification requires that all EJB client
> containers provide a per thread context class loader for
> dynamically loading system value classes. The per thread context
> class loader is accessed using the Thread method
> getContextClassLoader. [...]
>
>
> So that seems like I should be able to get the context ClassLoader in
> this fashion just fine.
>
> Then section EE.8.2.5 says:
>
> ...libraries that need to dynamically load classes that have been
> provided as a part of the application need to use the context
> class loader to load the classes. Access to the context class
> loader requires RuntimePermission(“getClassLoader”), which is not
> normally granted to applications, but should be granted to
> libraries that need to dynamically load classes. Libraries can use
> a method such as the following to assert their privilege when
> accessing the context class loader.
>
>
> So that sounds like in a Java EE 6 application it should be legal to
> obtain a ClassLoader via
> Thread.currentThread().getContextClassLoader(), and--reading the Java
> EJB specification section 21.2.2 very carefully--legal to call
> getResourceAsStream() on it, provided that--again, conforming to the
> EE specification--my library actually doing this resource access has
> been granted the appropriate RuntimePermission and has performed the
> class load as a privileged action.
>
> Is that correct?
>
> Best,
> Laird
>
> --
> http://about.me/lairdnelson
>