9 Replies Latest reply on Jan 4, 2005 3:14 PM by starksm64

    Override jboss-jmx.jar in 3.2.5?

    ctday

      There is a bug in the javax.management.monitor.Monitor class that prevents me from using StringMonitors. I know how to fix the code, but I'm looking at a production environment where I want to deploy the change with a minimum of effort. In particular, I don't want to get into building and maintaining my own version of Jboss 3.2.5. Is there any way through configuration - properties files, environment variables, etc. - to direct a booting Jboss to pick up my fixed version of Monitor before it loads jboss-jmx.jar? jboss.patch.dir sounds promising, but I don't know how to get it to function. Thanks.

        • 1. Re: Override jboss-jmx.jar in 3.2.5?
          starksm64

          The patchdir option adds the jar to the start of the bootstrap classpath and can be used to override the microkernel jars including jmx. Post the patch to jira.
          http://jira.jboss.com/jira/secure/JBJMX

          • 2. Re: Override jboss-jmx.jar in 3.2.5?
            ctday

            Patch posted to JIRA, but the patchdir option has me stumped. The fix works, since if I replace the class directly in $JBOSS_HOME/lib/jboss-jmx.jar, my program works correctly. However, if i make a jar with the corrected class, put the jar in a patches directory and use the --patchdir option, the program still throws the ClassCastException => the override isn't happening. Nevertheless, the boot.log shows that the Boot url list contains both my patches directory and my patch jar file and that a UnifiedClassLoader is created for the patch jar file.

            Actually, I don't understand how the override is supposed to work. The UCL of the patch jar has the boot URL class loader as its parent. This parent loader is explicitly given the $JBOSS_HOME/lib/jboss-jmx.jar as a URL to work from. If the UCL defers to its parent, doesn't that mean that the $JBOSS_HOME/lib/jboss-jmx.jar will always win out over a class with the same name in the patch jar? Any help would be appreciated. Thanks.

            • 3. Re: Override jboss-jmx.jar in 3.2.5?
              starksm64

              Ok, I thought the patchdir was added to the bootclasspath. The -L library option adds jars to the bootclasspath which could be used to override /lib jars.

              • 4. Re: Override jboss-jmx.jar in 3.2.5?
                ctday

                Well, the -L and -C options will override some ${JBOSS_HOME}/lib jars, but not xercesImpl.jar, xml-apis.jar, xalan.jar, jboss-jmx.jar, dom4j.jar, gnu-regexp.jar, or concurrent.jar. These are all explicitly fed to the ServerLoader by Main _before_ anything from the command line. So again, the override of jboss-jmx.jar fails.

                • 5. Re: Override jboss-jmx.jar in 3.2.5?
                  starksm64

                  Ok. Another option will have to be added then.

                  • 6. Re: Override jboss-jmx.jar in 3.2.5?
                    starksm64

                    I added another -B|-bootlib option to prepend jars to the bootclasspath. The 3.2 branch code diff against 3.2.5 is shown below.

                    [starksm@lamia jboss]$ cvs diff -r JBoss_3_2_5 Main.java
                    Index: Main.java
                    ===================================================================
                    RCS file: /cvsroot/jboss/jboss-system/src/main/org/jboss/Main.java,v
                    retrieving revision 1.17.2.13
                    retrieving revision 1.17.2.16
                    diff -r1.17.2.13 -r1.17.2.16
                    12a13
                    > import java.lang.reflect.Method;
                    13a15
                    > import java.net.URLDecoder;
                    25d26
                    < import org.jboss.system.server.ServerLoader;
                    26a28
                    > import org.jboss.system.server.ServerLoader;
                    44c46
                    < * @version $Revision: 1.17.2.13 $
                    ---
                    > * @version $Revision: 1.17.2.16 $
                    52c54
                    < private String jmxLibs = "jboss-jmx.jar,dom4j.jar,gnu-regexp.jar";
                    ---
                    > private String jmxLibs = "jboss-jmx.jar,dom4j.jar,jaxen.jar,gnu-regexp.jar";
                    55a58,62
                    > /** Extra jars added to the start of the boot classpath. This can be used
                    > to override jboss /lib boot classes
                    > */
                    > private List bootLibraries = new LinkedList();
                    >
                    98c105
                    < path = java.net.URLDecoder.decode(path);
                    ---
                    > path = urlDecode(path);
                    116a124,129
                    > // Add any extra libraries
                    > for (int i = 0; i < bootLibraries.size(); i++)
                    > {
                    > loader.addLibrary((String)bootLibraries.get(i));
                    > }
                    >
                    194a208
                    > new LongOpt("bootlib", LongOpt.REQUIRED_ARGUMENT, null, 'B'),
                    236a251
                    > System.out.println(" -B, --bootlib=<filename> Add an extra library to the front bootclasspth");
                    340a356,360
                    > case 'B':
                    > arg = getopt.getOptarg();
                    > bootLibraries.add(arg);
                    > break;
                    >
                    383a404,424
                    > * Decode the path depending upon whether we have java1.4 or java1.3 installed
                    > *
                    > * @param path the path to decode
                    > * @return the decoded path
                    > * @throws Exception for any error
                    > */
                    > private String urlDecode(String path) throws Exception
                    > {
                    > Method decode;
                    > try
                    > {
                    > decode = URLDecoder.class.getMethod("decode", new Class[] { String.class, String.class });
                    > return (String) decode.invoke(null, new Object[] { path, "UTF-8" });
                    > }
                    > catch (NoSuchMethodException e)
                    > {
                    > return URLDecoder.decode(path);
                    > }
                    > }
                    >
                    > /**
                    



                    • 7. Re: Override jboss-jmx.jar in 3.2.5?
                      ctday

                      Thanks. I will give it a try.

                      • 8. Re: Override jboss-jmx.jar in 3.2.5?
                        ctday

                        Almost. The problem with your patch, from my viewpoint, is that it uses ServerLoader.addLibrary(). This forces the javax-management-monitor-Monitor-patch.jar patch to jboss-jmx.jar to reside in the same directory as the rest of the boot JARs. That means that I either add my javax-management-monitor-Monitor-patch.jar patch JAR to the ${JBOSS_HOME}/lib directory, which means I'm directly fiddling with the Jboss distribution and I want to treat that as read-only, or I move all of ${JBOSS_HOME}/lib over to someplace under my own control, which means I am over-treating the correction. It seems that if the patch to Main uses ServerLoader.addURL() instead, I can keep the bulk of the boot JARs in ${JBOSS_HOME}/lib and still have the Monitor patch in a directory under my control. I include a proposed alternative patch to org.jboss.Main below based on the 3.2.5 version.

                        --- /cygdrive/c/jboss-3.2.5-src/system/src/main/org/jboss/Main.java 2004-06-15 11:44:28.000000000 -0700
                        +++ /cygdrive/c/eclipse/workspaceExo/Jboss-patches/org/jboss/Main.java 2004-12-30 12:48:25.956603200 -0800
                        @@ -10,7 +10,9 @@
                         package org.jboss;
                        
                         import java.io.File;
                        +import java.lang.reflect.Method;
                         import java.net.URL;
                        +import java.net.URLDecoder;
                         import java.net.MalformedURLException;
                         import java.util.Properties;
                         import java.util.List;
                        @@ -22,8 +24,8 @@
                        
                         import org.jboss.system.server.Server;
                         import org.jboss.system.server.ServerConfig;
                        -import org.jboss.system.server.ServerLoader;
                         import org.jboss.system.server.ServerConfigUtil;
                        +import org.jboss.system.server.ServerLoader;
                        
                         /**
                         * Provides a command line interface to start the JBoss server.
                        @@ -41,7 +43,7 @@
                         * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
                         * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
                         * @author <a href="mailto:adrian.brock@happeningtimes.com">Adrian Brock</a>
                        - * @version $Revision: 1.17.2.13 $
                        + * @version $Revision: 1.17.2.16 $
                         */
                         public class Main
                         {
                        @@ -49,10 +51,15 @@
                         private String jaxpLibs = "xercesImpl.jar,xml-apis.jar,xalan.jar";
                        
                         /** The JMX library to use. */
                        - private String jmxLibs = "jboss-jmx.jar,dom4j.jar,gnu-regexp.jar";
                        + private String jmxLibs = "jboss-jmx.jar,dom4j.jar,jaxen.jar,gnu-regexp.jar";
                        
                         private String concurrentLib = "concurrent.jar";
                        
                        + /** Extra jars added to the start of the boot classpath. This can be used
                        + to override jboss /lib boot classes
                        + */
                        + private List bootUrls = new LinkedList();
                        +
                         /** Extra libraries to load the server with .*/
                         private List extraLibraries = new LinkedList();
                        
                        @@ -95,7 +102,7 @@
                         * this path through the decoder so that is JBoss starts in a path with
                         * spaces we don't come crashing down.
                         */
                        - path = java.net.URLDecoder.decode(path);
                        + path = urlDecode(path);
                         File runJar = new File(path);
                         File homeFile = runJar.getParentFile().getParentFile();
                         homeDir = homeFile.getCanonicalPath();
                        @@ -114,6 +121,12 @@
                         // Load the server instance
                         ServerLoader loader = new ServerLoader(props);
                        
                        + // Add any extra libraries
                        + for (int i = 0; i < bootUrls.size(); i++)
                        + {
                        + loader.addURL((URL) bootUrls.get(i));
                        + }
                        +
                         // Add JAXP and JMX libs
                         loader.addLibraries(jaxpLibs);
                         loader.addLibraries(jmxLibs);
                        @@ -192,6 +205,7 @@
                         new LongOpt("configuration", LongOpt.REQUIRED_ARGUMENT, null, 'c'),
                         new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V'),
                         new LongOpt("jaxp", LongOpt.REQUIRED_ARGUMENT, null, 'j'),
                        + new LongOpt("bootlib", LongOpt.REQUIRED_ARGUMENT, null, 'B'),
                         new LongOpt("library", LongOpt.REQUIRED_ARGUMENT, null, 'L'),
                         new LongOpt("classpath", LongOpt.REQUIRED_ARGUMENT, null, 'C'),
                         new LongOpt("properties", LongOpt.REQUIRED_ARGUMENT, null, 'P'),
                        @@ -234,6 +248,7 @@
                         System.out.println(" -n, --netboot=<url> Boot from net with the given url as base");
                         System.out.println(" -c, --configuration=<name> Set the server configuration name");
                         System.out.println(" -j, --jaxp=<type> Set the JAXP impl type (ie. crimson)");
                        + System.out.println(" -B, --bootlib=<filename> Add an extra library to the front bootclasspth");
                         System.out.println(" -L, --library=<filename> Add an extra library to the loaders classpath");
                         System.out.println(" -C, --classpath=<url> Add an extra url to the loaders classpath");
                         System.out.println(" -P, --properties=<url> Load system properties from the given url");
                        @@ -338,6 +353,11 @@
                         break;
                         }
                        
                        + case 'B':
                        + arg = getopt.getOptarg();
                        + bootUrls.add(makeURL(arg));
                        + break;
                        +
                         case 'L':
                         arg = getopt.getOptarg();
                         extraLibraries.add(arg);
                        @@ -381,6 +401,27 @@
                         }
                        
                         /**
                        + * Decode the path depending upon whether we have java1.4 or java1.3 installed
                        + *
                        + * @param path the path to decode
                        + * @return the decoded path
                        + * @throws Exception for any error
                        + */
                        + private String urlDecode(String path) throws Exception
                        + {
                        + Method decode;
                        + try
                        + {
                        + decode = URLDecoder.class.getMethod("decode", new Class[] { String.class, String.class });
                        + return (String) decode.invoke(null, new Object[] { path, "UTF-8" });
                        + }
                        + catch (NoSuchMethodException e)
                        + {
                        + return URLDecoder.decode(path);
                        + }
                        + }
                        +
                        + /**
                         * This is where the magic begins.
                         *
                         * <P>Starts up inside of a "jboss" thread group to allow better
                        


                        • 9. Re: Override jboss-jmx.jar in 3.2.5?
                          starksm64

                          Ok, I created a feature request for this issue. I believe the patchdir behavior should simply be updated to what you describe as its currently not a useful option.

                          http://jira.jboss.com/jira/browse/JBAS-1265