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:35:26 -0800

Marina Vatkina wrote:
>
>
> N W wrote:
>> Restriction on the usage of File IO APIs?
>
> This restriction will become a work of caution in the EJB 3.2.

A word of caution...

-marina
>
> -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
>>>>
>>>>
>>
>>