users@glassfish.java.net

Re: GF 3.1.1 yet another classloading issue - JEE6 EAR packaging and MANIFEST.FM

From: Bernhard Thalmayr <bernhard.thalmayr_at_painstakingminds.com>
Date: Tue, 29 Nov 2011 22:08:57 +0100

On Tue, Nov 29, 2011 at 9:34 PM, Tim Quinn <tim.quinn_at_oracle.com> wrote:

>
> On Nov 29, 2011, at 2:11 PM, Bernhard Thalmayr wrote:
>
>
>
> On Tue, Nov 29, 2011 at 6:49 PM, Tim Quinn <tim.quinn_at_oracle.com> wrote:
>
>> Ah, this is such fun!
>>
>> If you look at the JavaDoc for URLClassLoader, you find this little
>> morsel:
>>
>> "This class loader is used to load classes and resources from a search
>> path of URLs referring to both JAR files and directories. Any URL that ends
>> with a '/' is assumed to refer to a directory. Otherwise, the URL is
>> assumed to refer to a JAR file which will be opened as needed. "
>>
>> Just about every useful class loader you'll come across extends
>> URLClassLoader, either directly or indirectly, so while the trailing slash
>> is NOT required by the manifest or JAR spec, it IS required by the
>> URLClassLoader contract.
>>
>
> Well ..... does this mandate that a directory mentioned in the
> 'Class-Path' header of MANIFEST.MF has a trailing slash?
>
> If the URLClassLoader needs this it could also be the responsibility of
> the container to add that slash .. isn't it?
>
>
> It is risky for the code to try to read the mind of the person who
> prepared the manifest, especially if that introduces differences in how an
> app server behaves with the same inputs compared to Java SE.
>
> Although it is true that a container could conceivably assume that the
> user intended any Class-Path entries that do not end in .jar to be
> directories, that would (1) contradict how Java SE treats such Class-Path
> entries, and (2) require the container to guess what the user intended.
>
> But let's go back to the 3rd party library which contains the slash-less
> directory entries in the Class-Path. Is there a runtime environment in
> which this library and its Class-Path entries are handled so that the
> slash-less directory IS added to the class path as a directory?
>


Thanks for your thoughts Tim, much appreciated.

I don't know if other environments are adding the slash-less directory to
the classpath.

I have to migrate application from GF 2.1.1 to GF 3.1.1.

The 3rd party app has not had any directory specified at all. The
'package-structure' has just been put into the EAR and worked well in GF
2.1.1.

Now I have to repackage the app to make GF 3.1.1 happy.

I'm not a too experienced developer so I read the spec ... and the spec
does not tell anything about a trailing slash. Due to this I ran into a
classloading issue.

I now placed all classes in a 'supporting libary' and put it into 'lib'
directory within the EAR.

The challenge is that one has to look at so many documents and none gives
the 'correct' answer.

Regards,
Bernhard

>
> - Tim
>
>
> -Bernhard
>
>
>
>> - Tim
>>
>>
>> On Nov 29, 2011, at 10:23 AM, Bernhard Thalmayr wrote:
>>
>>
>>
>> On Tue, Nov 29, 2011 at 5:08 PM, Cheng Fang <cheng.fang_at_oracle.com>wrote:
>>
>>> If you write a java app with the same structure, you will also get the
>>> same behavior. So not a Java EE or GlassFish bug.
>>>
>>> Yes, both jar files and directories can be members of Class-Path. This
>>> part is governed by Java Jar Specification.
>>>
>>
>> If I read
>>
>> http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html
>>
>> I don't see where it's sepcified that 'directories' need to thave a
>> trailing slash .... is this a litle inaccuracy?
>>
>> IIRC I can do 'new File("dir").mkdir()' ....
>>
>> -Bernhard
>>
>>>
>>> -cheng
>>>
>>>
>>> On 11/29/11 10:35 AM, Bernhard Thalmayr wrote:
>>>
>>> Thanks for the pointer Cheng.
>>>
>>> I removed the 'lib' prefixes (actually I know about lib-directory .. but
>>> this is a 3rd party app and I don't want to change to much at the beginnin)
>>> and put 'classes/' into 'Class-Path' header.
>>>
>>> BTW should I consider it as a bug that I the directory must have a
>>> trainling '/'?
>>>
>>> Unfortuantely I can not deploy the app anymore to an instance directly
>>> (using --target <instance>).
>>>
>>> Deploying for target 'domain' works, but when I try to create the
>>> application-reference I always get the following error .... I don't see any
>>> reason how this could be related to the change
>>>
>>> [#|2011-11-29T16:25:11.814+0100|SEVERE|glassfish3.1.1|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=157;_ThreadName=Thread-2;|GRIZZLY0039:
>>> Request URI is too large.
>>> java.nio.BufferOverflowException
>>> at
>>> com.sun.grizzly.tcp.http11.InternalInputBuffer.fill(InternalInputBuffer.java:765)
>>> at
>>> com.sun.grizzly.tcp.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:467)
>>> at
>>> com.sun.grizzly.http.ProcessorTask.parseRequest(ProcessorTask.java:861)
>>> at
>>> com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:692)
>>> at
>>> com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
>>> at
>>> com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
>>> at
>>> com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
>>> at
>>> com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
>>> at
>>> com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
>>> at
>>> com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
>>> at
>>> com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
>>> at
>>> com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
>>> at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
>>> at
>>> com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
>>> at
>>> com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
>>> at java.lang.Thread.run(Thread.java:722)
>>> |#]
>>>
>>> [#|2011-11-29T16:25:11.817+0100|SEVERE|glassfish3.1.1|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=157;_ThreadName=Thread-2;|GRIZZLY0051:
>>> ProcessorTask exception.
>>> java.lang.NullPointerException
>>> at java.nio.CharBuffer.put(CharBuffer.java:915)
>>> at com.sun.enterprise.
>>> web.accesslog.DefaultAccessLogFormatterImpl.appendRequestInfo
>>> (DefaultAccessLogFormatterImpl.java:494)
>>> at com.sun.enterprise.
>>> web.accesslog.DefaultAccessLogFormatterImpl.appendLogEntry
>>> (DefaultAccessLogFormatterImpl.java:264)
>>> at com.sun.enterprise.web.PEAccessLogValve.postInvoke
>>> (PEAccessLogValve.java:592)
>>> at
>>> com.sun.enterprise.web.VirtualServer$2.onParsingError(VirtualServer.java:1698)
>>> at
>>> com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:709)
>>> at
>>> com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
>>> at
>>> com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
>>> at
>>> com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
>>> at
>>> com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
>>> at
>>> com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
>>> at
>>> com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
>>> at
>>> com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
>>> at
>>> com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
>>> at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
>>> at
>>> com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
>>> at
>>> com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
>>> at java.lang.Thread.run(Thread.java:722)
>>> |#]
>>>
>>> Thanks and regards,
>>> Bernhard
>>>
>>> On Tue, Nov 29, 2011 at 1:51 PM, Cheng Fang <cheng.fang_at_oracle.com>wrote:
>>>
>>>> Hi Bernhard,
>>>>
>>>> Change Class-Path: lib/lib1.jar lib/lib2.jar classes to Class-Path:
>>>> lib/lib1.jar lib/lib2.jar classes/
>>>>
>>>> Another point is, in Java EE 6, EAR/lib/ is the default EAR
>>>> library-directory and all jars in that directory are automatically made
>>>> available to your application. Having them also in Class-Path results in
>>>> duplicates but that should affect functioning.
>>>>
>>>> -cheng
>>>>
>>>>
>>>> On 11/29/11 5:13 AM, Bernhard Thalmayr wrote:
>>>>
>>>> Hi experts,
>>>>
>>>> classloading and 'portable JEE application' seems to be very
>>>> challenging in GF 3.1.1
>>>>
>>>> I have a (3rd party) enterprise app with layout
>>>>
>>>> META-INF/application.xml
>>>> ejb1.jar
>>>> |_ META-INF/MANIFEST.FM (Class-Path: lib/lib1.jar lib/lib2.jar classes)
>>>>
>>>> ejb2.jar
>>>> |_META-INF/MANIFEST.FM (Class-Path: lib/lib1.jar lib/lib3.jar classes)
>>>>
>>>> lib/lib1.jar
>>>> lib/lib2.jar
>>>> lib/lib3.jar
>>>> classes/<package-structure>
>>>>
>>>> A 'NoClassDefFoundError' is raised
>>>>
>>>> java.lang.NoClassDefFoundError: <class-from-classes-directory>
>>>> at java.lang.ClassLoader.defineClass1(Native Method)
>>>> at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
>>>> at
>>>> com.sun.enterprise.loader.ASURLClassLoader.findClass(ASURLClassLoader
>>>> .java:756)
>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:410)
>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:410)
>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
>>>> at java.lang.Class.forName0(Native Method)
>>>> at java.lang.Class.forName(Class.java:186)
>>>> at <method-of-class-from-ejb1.jar>
>>>>
>>>>
>>>> As far as I interpret chapter 'EE.8' of JEE 6 specification I packaged
>>>> the appliation correctly.
>>>>
>>>> Could it be that GF 3.1.1 does not honour directories mentioned in
>>>> MANIFEST.FM ?
>>>>
>>>> Section 8.2.1 states ...
>>>>
>>>> "The Java EE deployment tools must process all such referenced files
>>>> and directories when processing a Java EE module."
>>>>
>>>> Thanks for any pointers.
>>>>
>>>> -Bernhard
>>>> --
>>>> IT-Consulting Bernhard Thalmayr
>>>> - Painstaking Minds -
>>>> 83620 Vagen (Munich area)
>>>> Germany
>>>>
>>>>
>>>
>>>
>>> --
>>> IT-Consulting Bernhard Thalmayr
>>> - Painstaking Minds -
>>> 83620 Vagen (Munich area)
>>> Germany
>>>
>>>
>>
>>
>> --
>> IT-Consulting Bernhard Thalmayr
>> - Painstaking Minds -
>> 83620 Vagen (Munich area)
>> Germany
>>
>>
>>
>
>
> --
> IT-Consulting Bernhard Thalmayr
> - Painstaking Minds -
> 83620 Vagen (Munich area)
> Germany
>
>
>


-- 
IT-Consulting Bernhard Thalmayr
- Painstaking Minds -
83620 Vagen (Munich area)
Germany