users@glassfish.java.net

Re: EE/EJB spec. conflict regarding classloading?

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

N W wrote:
> Restriction on the usage of File IO APIs?

This restriction will become a work of caution in the EJB 3.2.

-marina

> I think it would be a benefit to the platform to have the EE spec. require an impl. of a JCA Adapter for flat files.
>
> -Noah
>
> On Nov 9, 2011, at 1:53 PM, Marina Vatkina wrote:
>
>
>> 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
>>>
>>>
>
>