Thank you for reporting this bug and the associated fix. This is very helpful.
At 07:39 AM 5/28/2003 -0400, you wrote:
The current JMX implementation in Log4J is in violation of the JMX Specification versions 1.1 and 1.2. These specifications require that attribute names and parameter names on MBeans be valid Java identifiers.
See Chapter 2 of the JMX 1.1 or 1.2 Specification.
As a result, the JMX facade shipped with Log4J will not run on Sun's JMX Reference Implementation version 1.2. I have not tried version 1.1.
The attached patch fixes this problem by mangling the attribute and parameter names into legal Java identifiers.
The patch also flags attributes that do not support writes as read-only.
Thanks,
Bill
Index: java/org/apache/log4j/jmx/AbstractDynamicMBean.java
===================================================================
RCS file: /home/wrossi/cvsroot/log4j/src/java/org/apache/log4j/jmx/AbstractDynamicMBean.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 AbstractDynamicMBean.java
--- java/org/apache/log4j/jmx/AbstractDynamicMBean.java 26 May 2003 11:10:09 -0000 1.1.1.1
+++ java/org/apache/log4j/jmx/AbstractDynamicMBean.java 26 May 2003 12:23:24 -0000
@@ -116,6 +116,65 @@
return name;
}
+ protected + String toValidJavaIdentifier(String name) { + /* Remove any characters that arent legal in java identifiers */ + StringBuffer sb; + char nameChars[] = name.toCharArray();
+ sb = new StringBuffer();
+ if (name != null && name.length() > 0) {
+ if (Character.isJavaIdentifierStart(nameChars[0]))
+ sb.append(nameChars[0]);
+ else
+ sb.append("_");
+ }
+
+ if (name != null && name.length() > 1) {
+ for (int i=1; i<name.length(); i++) {
+ if (Character.isJavaIdentifierPart(nameChars[i]))
+ sb.append(nameChars[i]);
+ else
+ sb.append("_"+Integer.toHexString(nameChars[i])+"_");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ protected
+ String decodeJavaIdentifier(String id) {
+ /* Remove any characters that arent legal in java identifiers */
+ StringBuffer sb = new StringBuffer();
+ char nameChars[] = id.toCharArray();
+ int j;
+
+ getLogger().debug("decodeJavaIdentifier "+id);
+
+ for (int i=0; i<nameChars.length; i++) {
+ if (nameChars[i] == '_') {
+ // search forward for next underscore
+ for (j=i+1; j<nameChars.length; j++) {
+ if (nameChars[j] == '_')
+ break;
+ }
+
+ // Ran out of data? This shouldn't happen if input formated with toValidJavaIdentifier()
+ if (nameChars[j] != '_')
+ continue;
+
+ String hstr = new String(nameChars, i+1, j-i-1);
+ char c = (char) Integer.parseInt(hstr, 16);
+ sb.append(c);
+ i = j;
+ }
+ else {
+ sb.append(nameChars[i]);
+ }
+ }
+
+ getLogger().debug("decodeJavaIdentifier "+id+" -> "+sb.toString());
+ return sb.toString();
+ }
}
Index: java/org/apache/log4j/jmx/AppenderDynamicMBean.java
===================================================================
RCS file: /home/wrossi/cvsroot/log4j/src/java/org/apache/log4j/jmx/AppenderDynamicMBean.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 AppenderDynamicMBean.java
--- java/org/apache/log4j/jmx/AppenderDynamicMBean.java 26 May 2003 11:10:09 -0000 1.1.1.1
+++ java/org/apache/log4j/jmx/AppenderDynamicMBean.java 26 May 2003 23:54:09 -0000
@@ -105,7 +105,7 @@
MBeanOperationInfo.ACTION);
params = new MBeanParameterInfo[1];
- params[0] = new MBeanParameterInfo("layout class", "java.lang.String",
+ params[0] = new MBeanParameterInfo(toValidJavaIdentifier("layout class"), "java.lang.String",
"layout class");
dOperations[1] = new MBeanOperationInfo("setLayout", @@ -185,11 +185,12 @@ objectName = new ObjectName("log4j:appender="+name); server.registerMBean(appenderMBean, objectName);
- dAttributes.add(new MBeanAttributeInfo("appender="+name,
+ // Should be read-only
+ dAttributes.add(new MBeanAttributeInfo(toValidJavaIdentifier("appender="+name),
"javax.management.ObjectName",
"The "+name+" layout.",
true,
- true,
+ false,
false));
} catch(Exception e) { @@ -204,9 +205,12 @@
public
- Object getAttribute(String attributeName) throws AttributeNotFoundException,
+ Object getAttribute(String attrName) throws AttributeNotFoundException,
MBeanException,
ReflectionException {
+ String attributeName;
+
+ attributeName = decodeJavaIdentifier(attrName);
// Check attributeName is not null to avoid NullPointerException later on
if (attributeName == null) {
@@ -258,7 +262,7 @@
"Cannot invoke a setter of " + dClassName +
" with null attribute");
}
- String name = attribute.getName();
+ String name = decodeJavaIdentifier(attribute.getName());
Object value = attribute.getValue();
if (name == null) {
Index: java/org/apache/log4j/jmx/HierarchyDynamicMBean.java
===================================================================
RCS file: /home/wrossi/cvsroot/log4j/src/java/org/apache/log4j/jmx/HierarchyDynamicMBean.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 HierarchyDynamicMBean.java
--- java/org/apache/log4j/jmx/HierarchyDynamicMBean.java 26 May 2003 11:10:09 -0000 1.1.1.1
+++ java/org/apache/log4j/jmx/HierarchyDynamicMBean.java 26 May 2003 11:42:23 -0000
@@ -118,7 +118,7 @@
nbs.addNotificationListener(loggerMBean, nfs, null);
- vAttributes.add(new MBeanAttributeInfo("logger="+name,
+ vAttributes.add(new MBeanAttributeInfo(toValidJavaIdentifier("logger="+name),
"javax.management.ObjectName",
"The "+name+" logger.",
true,
Index: java/org/apache/log4j/jmx/LoggerDynamicMBean.java
===================================================================
RCS file: /home/wrossi/cvsroot/log4j/src/java/org/apache/log4j/jmx/LoggerDynamicMBean.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 LoggerDynamicMBean.java
--- java/org/apache/log4j/jmx/LoggerDynamicMBean.java 26 May 2003 11:10:09 -0000 1.1.1.1
+++ java/org/apache/log4j/jmx/LoggerDynamicMBean.java 26 May 2003 23:49:51 -0000
@@ -84,9 +84,9 @@
MBeanParameterInfo[] params = new MBeanParameterInfo[2];
- params[0] = new MBeanParameterInfo("class name", "java.lang.String",
+ params[0] = new MBeanParameterInfo(toValidJavaIdentifier("class name"), "java.lang.String",
"add an appender to this logger");
- params[1] = new MBeanParameterInfo("appender name", "java.lang.String",
+ params[1] = new MBeanParameterInfo(toValidJavaIdentifier("appender name"), "java.lang.String",
"name of the appender");
dOperations[0] = new MBeanOperationInfo("addAppender", @@ -134,10 +134,13 @@
public
- Object getAttribute(String attributeName) throws AttributeNotFoundException,
+ Object getAttribute(String attrName) throws AttributeNotFoundException,
MBeanException,
ReflectionException {
+ String attributeName;
+ attributeName = decodeJavaIdentifier(attrName);
+
// Check attributeName is not null to avoid NullPointerException later on
if (attributeName == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
@@ -198,7 +201,7 @@
"Cannot invoke a setter of " + dClassName +
" with null attribute");
}
- String name = attribute.getName();
+ String name = decodeJavaIdentifier(attribute.getName());
Object value = attribute.getValue();
if (name == null) { @@ -244,11 +247,12 @@ objectName = new ObjectName("log4j", "appender", name); server.registerMBean(appenderMBean, objectName);
- dAttributes.add(new MBeanAttributeInfo("appender="+name,
+ // This should be read-only.
+ dAttributes.add(new MBeanAttributeInfo(toValidJavaIdentifier("appender="+name),
"javax.management.ObjectName",
"The "+name+" appender.",
true,
- true,
+ false,
false));
} catch(Exception e) { --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--
Ceki For log4j documentation consider "The complete log4j manual"
ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]