On Fri, Nov 14, 2014 at 7:08 PM, Konstantin Kolinko <knst.koli...@gmail.com> wrote: > 2014-11-15 0:57 GMT+03:00 Matt Newell <dycs...@gmail.com>: >> On Fri, Nov 14, 2014 at 3:28 PM, Christopher Schultz >> <ch...@christopherschultz.net> wrote: >>> On 11/14/14 1:14 PM, Matt Newell wrote: >>>> Greetings, >>>> >>>> I have a need to get version information for classes that I have >>>> been packaged in a war, and loaded into Tomcat 7.0.trunk on Windows >>>> 7. For example: >>>> >>>> >>>> System.out.println(this.getClass().getPackage().getImplementationVersion()); >>>> >>>> Assuming my.war/META-INF/MANIFEST.MF: Manifest-Version: 1.0 >>>> Implementation-Version: 1.0 >>>> >>>> getImplementationVersion() always returns null. >>>> >>>> If I review the code for WebappClassLoader the reason for this is >>>> clear. All roads lead to findResourceInternal(File, String), line >>>> 2983 in 7.x/trunk. This method makes no attempt to load the >>>> manifest from the war. >>>> >>>> My first instinct was that this is a bug. However, I did a quick >>>> check using the same scenario using Wildfly 8 and the behavior is >>>> the same. Given the clarity of the Tomcat code, and that two >>>> robust, well-tested platforms behave the same, I have to assume >>>> this is intentional. >>>> >>>> My question is this: why? Is META-INF/MANIFEST.MF not part of the >>>> war standard? I've googled, but am not enough of a java standards >>>> wonk to know what docs are authoritative on this topic. I've >>>> certainly seen examples that use it. >>> >>> If Tomcat can't/won't do this, you can always load the manifest >>> manually (context.getResource*) and grab the Implementation-Version >>> from it. >> >> Chris, >> >> Agreed. Ultimately I am likely to leverage some approach along these >> lines. Just thought it was odd that tomcat didn't populate the data >> structures I expected. >> >> In my particular case, however, this approach is limiting. My use case >> is to get version information from *all* loaded wars. Specifically >> pulling resources from ServletContext or the available ClassLoader is >> limited to resources within the current war. >> >> java.lang.Package.getPackages() doesn't have this limitation, it seems >> to pull packages loaded via all ClassLoaders. But it only works if the >> ClassLoader populated the metadata from META-INF/MANIFEST.MF when >> loading a class. >> >> Otherwise, I've got to build a startup hook into each war that reads >> its manifest, and writes version info to some global space. >> Properties, maybe? Ugly. But, ya do what ya gotta. > > 1. What if the web application does not have a war file, but is > deployed as an expanded directory?
Personally, I don't see how our expectations would change in this scenario. As comparison, we load classes from the same relative location whether exploded or not. However, see below. > 2. Please find some specification references. > 3. If there were a manifest for the WEB-INF/classes/ I would wonder > whether it is META-INF/MANIFEST.MF or > WEB-INF/classes/META-INF/MANIFEST.MF. Why prefer the former rather > than the latter? I think that none of them is applicable. I assume the Servlet Spec (JSR-000340) is authoritative. Unfortunately, I find it vague. Section 10.5 speaks to the directory structure, but makes no mention of META-INF, except in the context of an included jar. Section 10.6 describes a packaged war, and describes META-INF, but isn't specific to it's location. From the spec: "When packaged into such a form, a META-INF directory will be present which contains information useful to Java archive tools." You could read these two sections to conclude that META-INF only applies to a packaged war, not an expanded directory. That seems an odd conclusion, however, since more times than not, we arrive at an expanded directory by unzipping a war, and therefore whatever was present in the war, would be in the directory. Either way, the spec makes no specific reference to MANIFEST.MF or the metadata within. I'd be glad to do more reading, but I'm not sure what other docs would apply. > 4. Are there any precedents? Discussions? Not sure what passes for a valid precedent around here. I had a look at jetty, which strikes me as interesting and relevant as the simplest implementation of the servlet spec. Its WebAppClassLoader is extremely basic. In this case it ends up delegating to java.net.URLClassLoader.defineClass(String, Resource). This method also defines the Package with all null metadata fields, consistent to the behavior of Tomcat. Given that a core java class also has the same behavior, it strengthens the argument that this is expected. Yet, it still strikes me as odd. java.lang.Package is significantly less useful if it isn't populated with metadata from MANIFEST.MF. I don't find any discussions that are particularly compelling. There are a few here and there: http://stackoverflow.com/questions/11139643/what-is-use-of-manifest-mf-in-war-jar-ear http://stackoverflow.com/questions/4239368/how-to-read-manifest-mf-inside-war-application http://blog.frankel.ch/get-the-handle-on-the-manifest-mf-in-a-webapp Most lead towards the solution that Chris originally proposed, rather than a discussion of the standard. It is interesting that maven provides a plugin for creating META-INF/MANIFEST.MF in wars: http://maven.apache.org/plugins/maven-war-plugin/examples/war-manifest-guide.html Given the existence of this plugin, I would assume that other users are creating META-INF/MANIFEST.MF for wars, but I have to assume everyone is reading it back manually as a resource, rather than relying on the various ClassLoaders populating the metadata to Package. Which, truthfully, given this analysis, will end up being more robust across platforms, if not the only option. If anyone thinks there is useful investigation beyond what I've done, I'm open to it. Otherwise, I'm inclined to let this die. Thanks, -- m. > Best regards, > Konstantin Kolinko > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org