Date
1 - 7 of 7
Annotation scanning with java 9 multi version jars
bitonti@...
Hi,
I don't see an application of MR to EAR, but EARs don't package classes directly, so that seems natural. (But are there any resource loading cases for EAR files?) Reasons that I'm finding that suggest that WAR should support MR is that (1) the extension seems straightforward; and (2) the use of MR for other module types is direct, meaning, MR enablement may be likely for other module types (3) having fragment JARs support MR but having the WAR itself not seems exceptional behavior. In any case, if fragment JARS *do* support MR, we still have the main question: What are the rules for scanning annotations? My simplest answer is that since JavaEE/servlet annotations are an alternate to metadata which can be specified in a descriptor, and descriptors live in WEB-INF (or META-INF), and those are single versioned, then, JavaEE/servlet annotations should be single versioned. Then, all annotations must be present in base class versions, and no alteration is permitted (or is visible) in MR version specific classes. I presume that this applies to not only descriptor type annotations, but also to Servlet Container Initializer (SCI) related annotations. Despite this rule, there might be a problem, in that annotation processing can involve class relationships (superclasses and interfaces). Would superclasses or interfaces be allowed to vary for annotated classes across MR versions? Thx! Thomas Bitonti |
|
Greg Wilkins
I agree with Mark, I don't believe that MR behaviour should necessarily apply to WAR and EAR files. Sure if you give war file to a java9 ClassLoader, it will happily version WEB-INF/web.xml. However it is not a correct thing to do to give a war file to a java9 ClassLoader, as it will not be able to load any classes from WEB-INF/classes (versioned or not). So while a war is a jar, it is not a classloadable jar. Also the precedent set by the java9 ClassLoader itself is that meta-data is not versioned - ie all of META-INF is excluded from versioning. It's thus reasonable to say that MR considerations should not automagically apply to WEB-INF either. Furthermore, I see no reason for a war file to support MR in any way other than WEB-INF/lib may contain MR jars. Versioning other resources in a war makes no sense as any selection of resourced based on version surely should be the client version not the server version? regards On 15 January 2018 at 13:17, Mark Thomas <markt@...> wrote: On 09/01/18 15:18, bitonti@... wrote: --
|
|
Mark Thomas
On 09/01/18 15:18, bitonti@... wrote:
Hi,My starting position is the opposite. The summary in JEP 238 starts: "Extend the JAR file format to allow multiple, Java-release-specific versions of class files to coexist in a single archive." That says to me, multi-release features are intended only for classes. Secondly, WAR files do not implement all the features of JARs. See the glossary of the Servlet spec for some explicit examples. Therefore, unless the behaviour is explicitly called out in the Servlet spec my starting position is that a WAR file does not support it. Mark For WAR files there seem to |
|
bitonti@...
Hi,
Looking over the JEP238 and JavaDoc, the focus is on resource lookup. I don't see any behavior which distinguishes a class type resource from a non-class type resource. Once a resource is available in a JAR it never goes away. Once the resource of a member class is available at a MR version, it remains available at all higher MR versions. From a metadata perspective, I'm seeing mixed directions. Metadata which is provided beneath META-INF is fixed across all MR versions. But, module descriptors can be MR version specific. Module "uses" clauses can be MR version specific. Then, does that imply a need to handle different class paths for JavaEE modules -- which contradicts that META-INF metadata is fixed? From an annotation scanning perspective, the best I've determined is that some annotations will be independent of MR version (probably anything that can be mapped back to module descriptors, which live in META-INF, and which is MR version independent), while other annotations are tied to class details and will vary across MR versions (for example, @Trivial, which WebSphere uses for dynamic trace injection.) The question that I have is whether any JavaEE active annotations would be of the runtime type, meaning, allowed to vary by MR version. I presume that WAR and RAR files, as specializations of JAR files, automatically acquire the MR JAR behavior. For WAR files there seem to be questions about how exactly to map base resources to the MR version specific locations, e.g., should "WEB-INF/classes" be discarded. (A simplistic extension of MR JAR function to WAR files would not be aware of "WEB-INF" as a distinguished directory and would carry that into the mapped MR version specific locations.) Thx! Thomas Bitonti IBM - WebSphere Application Server |
|
Greg Wilkins
All, I've had a conversations regarding this issue on jigsaw-dev and core-libs-dev. While there was some acknowledgement that the JarFile API is incomplete regarding support for Multi Release jars, there was not much enthusiasm taking on the responsibility of filtering out non applicable classes. Specifically I proposed: the stream needs to handle inner classes and only include them and provided a proposed implementation: to which the response from Alan Bateman at oracle was: I don't think this should be pushed down to the JarFile API. The JarFile So if that view prevails, then it is up to the application specification and container developers to agree on a semantic of what classes will be scanned, else we will have a major portability problem. There were several responses in the discussion there that indicated that such problems are already being seen in the wild as libraries are being released using this features in advance of the tools being able to cope. So it would be really great if we could come up with an agreement on how to apply interpret the "semantic relationships" within a MR Jar. I think the main driver for my proposal are that: it avoids the need to analyse the class files to determine relationships and applicability; b) it is a likely default layout for MR jars; c) it has defensible semantics. However, I think it more important that there is an agreed portable interpretation, rather than any one interpretation, so happy to consider other proposals. cheers On 14 September 2017 at 03:28, Mark Thomas <markt@...> wrote: On 13/09/2017 01:02, Greg Wilkins wrote: |
|
Mark Thomas
On 13/09/2017 01:02, Greg Wilkins wrote:
Likewise. We are already seeing these jars in our java 8 deployments (from someWe (Tomcat) haven't had any reports of problems in this area yet. It is on the list of things to worry about (and thanks for setting out the problems so clearly) but we haven't looked at a solution yet. The convention that any versioned class would also version all of it's inner classes sounds like a reasonable solution to me. Have you asked about this on jigsaw-dev@... ? Cheers, Mark |
|
Greg Wilkins
We are a bit concerned with providing reasonable support for annotation scanning in java 9 multi version jars. We are already seeing these jars in our java 8 deployments (from some logging frameworks), so we are having to update our scanning to ignore the versioned classes (as they can't be java 8). However, we want to update our scanning to support running on java 9, but just cannot work out a good algorithm for doing so, specially when confronted with inner classes. A multi versioned jar might contain something like:
So it is clear that there is a java 9 version of Foo. But what is unclear is the inner class Foo$Bar? Is that only used by the base Foo version? or does the java 9 version also use the Foo$Bar inner class, but it didn't use any java 9 features, so the base version is able to be used?? So it looks like we are going to need to analyse the actual Foo class version used to see if Foo$Bar is referenced and only then scan Foo$Bar for annotations (and recursive analysis for Foo$Bar$Bob class )! It means that given the index only of a jar, it is impossible to come up with the list of classes that will be provided by that jar for a given JVM! The only alternative would be if there was an enforced convention that any versioned class would also version all of it's inner classes - which may be a reasonable assumption given that they would be compiled together, but we see nothing in the specifications that force a jar to be assembled that way. Is this something the other containers are assuming (ie if there is no META-INF/versions/9/org/example/Foo$Bar.class, then the inner class is not used by the versioned outer class and thus do not scan org/example/Foo$Bar.class)? Or are we going to have to engage in code analysis just to determine which classes we need to analyse for annotations? regards -- |
|