Scanning multi version jars?
Stephen Felts
stephen.felts at oracle.com
Sat Sep 16 00:29:03 UTC 2017
FWIW I tracked down the MR jar file that I was having trouble with. It's the stand-alone JAXWS jar file com.sun.xml.ws.jaxws-rt.jar.
Focusing on the problem class, the jar contains
com/sun/xml/ws/util/xml/XmlCatalogUtil$1.class
com/sun/xml/ws/util/xml/XmlCatalogUtil.class
META-INF/versions/9/com/sun/xml/ws/util/xml/XmlCatalogUtil.class
The inner class XmlCatalogUtil$1.class is not used by the JDK9 version of the outer class. Further, XmlCatalogUtil$1.class has class/method references that will not be resolved on JDK9.
If the stream includes the inner class, it's possible that whatever is processing it will fail.
In the use case that I had for processing jar files, we generated a collection of all class names in the jar file, and then removed class file names as Greg proposed.
In the above example, com/sun/xml/ws/util/xml/XmlCatalogUtil$1.class and com/sun/xml/ws/util/xml/XmlCatalogUtil.class are removed.
Processing of the class files can only proceed after we generate/modify the entire list for the jar.
It ignores the possibility that a class outside the jar could be referencing something in the inner class that is public.
-----Original Message-----
From: Greg Wilkins [mailto:gregw at webtide.com]
Sent: Friday, September 15, 2017 5:59 PM
To: Alan Bateman <alan.bateman at oracle.com>
Cc: jigsaw-dev <jigsaw-dev at openjdk.java.net>; core-libs-dev at openjdk.java.net
Subject: Re: Scanning multi version jars?
Alan,
I had a quick look at `jdk.internal.util.jar.VersionedStream` and have the following comments:
- The style of the API is fine - pass in a JarFile and get a
Stream<JarEntry>.
- It might be better to have a Stream<VersionedJarEntry> which includes
a method to query the actual version of each entry.
- I think the stream needs to handle inner classes and only include them
if their matching outerclass is available at the same version. So for
example a base Foo$Bar.class will only be included if the stream includes a
base Foo.class, and it will not be included if the Foo.class is version 9
or above. Likewise a version 9 Foo$Bar.class will only be included in the
stream if the stream also includes a version 9 Foo.class, and will not be
included if the stream has a version 10 or above Foo.class
If you think this last point is possible, then I'll move the discussion back the EE expert groups to try to get an agreement on the exact stream code that will be used in the mid term until it is available in the JRE lib, at which time the specs should be amended to say they will defer the decision of which classes to scan the JRE lib so they will be future proof for any changes in java 10, 11 etc.
cheers
On 15 September 2017 at 17:27, Alan Bateman <Alan.Bateman at oracle.com> wrote:
>
>
> On 15/09/2017 03:09, Greg Wilkins wrote:
>
>>
>> Alan,
>>
>> thanks for correcting me on the API of JarFile - I can see it kind of
>> works, but in a very bizarre way (it gives different content for
>> entries obtained via the enumerator vs the getJarEntry API, even
>> though both entries report the same name). But I'll discuss that elsewhere.
>>
> This is something that was discussed on core-libs-dev on a number of
> occasions. The summary is that JarFile needs a new API for this,
> versionedStream() was suggested, but it was kicked down the road for
> later in order deal with the fallout from adding MR JARs.
>
> Since you have access to the code then look at
> jdk.internal.util.jar.VersionedStream for an example code of what I
> think you are looking for.
>
> -Alan
>
--
Greg Wilkins <gregw at webtide.com> CTO http://webtide.com
More information about the jigsaw-dev
mailing list