Bug 682116

Summary: PluginTransformer fails to read plug-in version from MANIFEST.MF because MANIFEST.MF is not the first file in the META-INF directory
Product: [Other] RHQ Project Reporter: bkramer <bkramer>
Component: PluginsAssignee: Charles Crouch <ccrouch>
Status: CLOSED CURRENTRELEASE QA Contact: Mike Foley <mfoley>
Severity: medium Docs Contact:
Priority: medium    
Version: 3.0.1CC: ccrouch, hbrock, ldimaggi, loleary
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 705091 726145 769967 (view as bug list) Environment:
JON 2.4.1 java version "1.6.0_24" Java(TM) SE Runtime Environment (build 1.6.0_24-b07) Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode)
Last Closed: 2013-09-03 12:59:51 EDT Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Bug Depends On:    
Bug Blocks: 725852, 705091, 753929    
Attachments:
Description Flags
Possible patch
none
Possible patch v2 none

Description bkramer 2011-03-04 02:59:12 EST
Description of problem:

The following exceptions are logged in the agent.log file for every plugins jar after fresh install of JON 2.4.1 + JON plugins for EAP 2.4.1:

2011-03-01 17:15:37,579 INFO  [main] (org.rhq.core.pc.PluginContainer)- Initializing Plugin Container v3.0.1.GA...
2011-03-01 17:15:40,244 ERROR [main] (rhq.core.pc.plugin.PluginManager)- Plugin [JMX] at [file:/apps/jboss/jon-agent/rhq-agent/plugins/rhq-jmx-plugin-3.0.1.GA.jar] could not be loaded and will therefore not be deployed.
org.rhq.core.clientapi.descriptor.PluginTransformException: No version is defined for plugin jar [file:/apps/jboss/jon-agent/rhq-agent/plugins/rhq-jmx-plugin-3.0.1.GA.jar]. A version must be defined either via the MANIFEST.MF 'Implementation-Version' attribute or via the plugin descriptor 'version' attribute.
	at org.rhq.core.clientapi.descriptor.PluginTransformer.getVersion(PluginTransformer.java:105)
	at org.rhq.core.clientapi.descriptor.PluginTransformer.toPlugin(PluginTransformer.java:70)
	at org.rhq.core.pc.plugin.PluginManager$1.execute(PluginManager.java:186)
	at org.rhq.core.pc.plugin.PluginManager.loadPlugin(PluginManager.java:341)
	at org.rhq.core.pc.plugin.PluginManager.initialize(PluginManager.java:156)
	at org.rhq.core.pc.PluginContainer.startContainerService(PluginContainer.java:391)
	at org.rhq.core.pc.PluginContainer.initialize(PluginContainer.java:252)
	at org.rhq.enterprise.agent.AgentMain.startPluginContainer(AgentMain.java:1748)
	at org.rhq.enterprise.agent.AgentMain.start(AgentMain.java:643)
	at org.rhq.enterprise.agent.AgentMain.main(AgentMain.java:413)
2011-03-01 17:15:40,529 ERROR [main] (rhq.core.pc.plugin.PluginManager)- Plugin [JBossAS5] at [file:/apps/jboss/jon-agent/rhq-agent/plugins/jopr-jboss-as-5-plugin-3.0.1.GA.jar] could not be loaded and will therefore not be deployed.
org.rhq.core.clientapi.descriptor.PluginTransformException: No version is defined for plugin jar [file:/apps/jboss/jon-agent/rhq-agent/plugins/jopr-jboss-as-5-plugin-3.0.1.GA.jar]. A version must be defined either via the MANIFEST.MF 'Implementation-Version' attribute or via the plugin descriptor 'version' attribute.
	at org.rhq.core.clientapi.descriptor.PluginTransformer.getVersion(PluginTransformer.java:105)
	at org.rhq.core.clientapi.descriptor.PluginTransformer.toPlugin(PluginTransformer.java:70)
	at org.rhq.core.pc.plugin.PluginManager$1.execute(PluginManager.java:186)
	at org.rhq.core.pc.plugin.PluginManager.loadPlugin(PluginManager.java:341)
	at org.rhq.core.pc.plugin.PluginManager.initialize(PluginManager.java:156)
	at org.rhq.core.pc.PluginContainer.startContainerService(PluginContainer.java:391)
	at org.rhq.core.pc.PluginContainer.initialize(PluginContainer.java:252)
	at org.rhq.enterprise.agent.AgentMain.startPluginContainer(AgentMain.java:1748)
	at org.rhq.enterprise.agent.AgentMain.start(AgentMain.java:643)
	at org.rhq.enterprise.agent.AgentMain.main(AgentMain.java:413)
2011-03-01 17:15:40,591 ERROR [main] (rhq.core.pc.plugin.PluginManager)- Plugin [JBossCache3] at [file:/apps/jboss/jon-agent/rhq-agent/plugins/jopr-jboss-cache-v3-plugin-3.0.1.GA.jar] could not be loaded and will therefore not be deployed.
...

However, auto-discovery seems to work properly.


Version-Release number of selected component (if applicable):

JON 2.4.1 


How reproducible:
Every time

Steps to Reproduce:
1. install JON 2.4.1
2. install EAP Plugin Pack for JON 2.4.1 
3. run JON agent;
  
Actual results:
The exception above are logged for every plugin jar;

Expected results:
There shouldn't be any exceptions...


Additional info:
Comment 1 Larry O'Leary 2011-03-10 22:31:52 EST
This issue is caused by calling getManifest() from JarInputStream which is a long running Sun JVM bug identified in:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4338238
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5046178
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4696354


From the looks of it, the implementation requires the MANIFEST.MF file to be the first entry in META-INF. All the JARs which trigger the error message have been packaged with the MANIFEST.MF falling later in the META-INF directory. This seems like a packaging issue.

Archive:  jopr-jboss-as-5-plugin-3.0.1.GA.jar
Archive:  jopr-jboss-as-plugin-3.0.1.GA.jar
Archive:  jopr-jboss-cache-v3-plugin-3.0.1.GA.jar
Archive:  jopr-rhq-server-plugin-3.0.1.GA.jar
Archive:  rhq-ant-bundle-plugin-3.0.1.GA.jar
Archive:  rhq-apache-plugin-3.0.1.GA.jar
Archive:  rhq-augeas-plugin-3.0.1.GA.jar
Archive:  rhq-jmx-plugin-3.0.1.GA.jar
Archive:  rhq-postgres-plugin-3.0.1.GA.jar


The result will be the plug-in container throwing several error messages on initialization as it attempts to get the version information of the plug-ins. Although the plug-ins appear to eventually be loaded, this state means that version information used in determining plug-in version information for the purpose of upgrade/update may fail.
Comment 2 Heiko W. Rupp 2011-03-16 15:54:17 EDT
Created attachment 485821 [details]
Possible patch
Comment 3 Heiko W. Rupp 2011-03-17 05:37:25 EDT
Created attachment 485963 [details]
Possible patch v2

This version of the patch checks if the url is a file url and then uses a JarFile.
Otherwise the JarInputStream is used so that jndi:/ urls will still work for EmbJopr.

See also https://issues.jboss.org/browse/EMBJOPR-274
Comment 4 Larry O'Leary 2011-03-18 13:42:36 EDT
I tested the patch in my instance and it does resolve the issue. I can not see any side affects from such a fix either.

Of course, I am guessing that this same exception/error is occurring in EAP admin-console and this patch would not resolve that issue.

Maybe further discussion is necessary?
Comment 5 Ian Springer 2011-03-25 12:44:33 EDT
Yes another bug for the JarInputStream limitation: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4263225
Comment 6 Ian Springer 2011-03-25 12:58:56 EDT
Right, Heiko's patch is not going to clear up the error messages in the admin console, since it only handles the file URL case. I think the best way to go to fix this on the admin console side would be to first try to obtain the manifest via JarInputStream.getManifest(). If getManifest() returns null, then iterate all entries in the jarfile looking for a META-INF/MANIFEST.MF entry; if one is found, then obtain the manifest using "new Manifest(manifestEntryInputStream)". If not, then the jarfile truly does not contain a manifest. In fact, this solution would work for both the RHQ/JON and admin-console sides and so could replace the previous patch.
Comment 7 Ian Springer 2011-03-25 15:03:17 EDT
Fixed in master (commit 5e63bfc) with the following updated impl of PluginTransformer.getVersionFromPluginJarManifest():

private String getVersionFromPluginJarManifest(URL pluginJarUrl) throws IOException {
        JarInputStream jarInputStream = new JarInputStream(pluginJarUrl.openStream());
        Manifest manifest = jarInputStream.getManifest();
        if (manifest == null) {
            // BZ 682116 (ips, 03/25/11): The manifest file is not in the standard place as the 2nd entry of the JAR,
            // but we want to be flexible and support JARs that have a manifest file somewhere else, so scan the entire
            // JAR for one.
            JarEntry jarEntry;
            while((jarEntry = jarInputStream.getNextJarEntry()) != null) {
                if (JarFile.MANIFEST_NAME.equalsIgnoreCase(jarEntry.getName())) {
                    manifest = new Manifest(jarInputStream);
                    break;
                }
            }
        }
        try {
            jarInputStream.close();
        } catch (IOException e) {
            LOG.error("Failed to close plugin jar input stream for plugin jar [" + pluginJarUrl + "].", e);
        }
        if (manifest != null) {
            Attributes attributes = manifest.getMainAttributes();
            return attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
        } else {
            return null;
        }
    }
Comment 8 Ian Springer 2011-03-30 17:20:28 EDT
Fixed in release-3.0.1 (commit 07e8c7b) using the same code applied to master.
Comment 11 Heiko W. Rupp 2013-09-03 12:59:51 EDT
Bulk closing of old issues that are in VERIFIED state.