You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by dr...@apache.org on 2013/04/03 19:33:10 UTC

svn commit: r1464116 - /river/jtsk/branches/2.2/src/com/sun/jini/logging/Levels.java

Author: dreedy
Date: Wed Apr  3 17:33:10 2013
New Revision: 1464116

URL: http://svn.apache.org/r1464116
Log:
RIVER-416: Fix for CustomLevel

Modified:
    river/jtsk/branches/2.2/src/com/sun/jini/logging/Levels.java

Modified: river/jtsk/branches/2.2/src/com/sun/jini/logging/Levels.java
URL: http://svn.apache.org/viewvc/river/jtsk/branches/2.2/src/com/sun/jini/logging/Levels.java?rev=1464116&r1=1464115&r2=1464116&view=diff
==============================================================================
--- river/jtsk/branches/2.2/src/com/sun/jini/logging/Levels.java (original)
+++ river/jtsk/branches/2.2/src/com/sun/jini/logging/Levels.java Wed Apr  3 17:33:10 2013
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License. You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,59 +20,62 @@ package com.sun.jini.logging;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
 import java.io.OutputStream;
 import java.io.Serializable;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
- * Defines additional {@link Level} values. <p>
- * <p/>
- * See the {@link LogManager} class for one way to use the <code>FAILED</code>
- * and <code>HANDLED</code> logging levels in standard logging configuration
- * files.
- *
- * @since 2.0
- */
+* Defines additional {@link Level} values. <p>
+* <p/>
+* See the {@link LogManager} class for one way to use the <code>FAILED</code>
+* and <code>HANDLED</code> logging levels in standard logging configuration
+* files.
+*
+* @since 2.0
+*/
 public class Levels {
 
     /**
-     * <code>FAILED</code> is a message level indicating that a facility has
-     * experienced a failure that it will reflect to its caller. <p>
-     * <p/>
-     * <code>FAILED</code> messages are intended to provide users with
-     * information about failures produced by internal components in order to
-     * assist with debugging problems in systems with multiple components. This
-     * level is initialized to <code>600</code>.
-     */
+    * <code>FAILED</code> is a message level indicating that a facility has
+    * experienced a failure that it will reflect to its caller. <p>
+    * <p/>
+    * <code>FAILED</code> messages are intended to provide users with
+    * information about failures produced by internal components in order to
+    * assist with debugging problems in systems with multiple components. This
+    * level is initialized to <code>600</code>.
+    */
     public static final Level FAILED = createLevel("FAILED", 600, null);
 
     /**
-     * <code>HANDLED</code> is a message level indicating that a facility has
-     * detected a failure that it will take steps to handle without reflecting
-     * the failure to its caller. <p>
-     * <p/>
-     * <code>HANDLED</code> messages are intended to provide users with
-     * information about failures detected by internal components in order to
-     * assist with debugging problems in systems with multiple components. This
-     * level is initialized to <code>550</code>.
-     */
+    * <code>HANDLED</code> is a message level indicating that a facility has
+    * detected a failure that it will take steps to handle without reflecting
+    * the failure to its caller. <p>
+    * <p/>
+    * <code>HANDLED</code> messages are intended to provide users with
+    * information about failures detected by internal components in order to
+    * assist with debugging problems in systems with multiple components. This
+    * level is initialized to <code>550</code>.
+    */
     public static final Level HANDLED = createLevel("HANDLED", 550, null);
 
     /**
-     * This class cannot be instantiated.
-     */
+    * This class cannot be instantiated.
+    */
     private Levels() {
         throw new AssertionError("This class cannot be instantiated");
     }
 
     /**
-     * Defines a class that has the same data format as the Level class, to
-     * permit creating the serialized form of a Level instance.
-     */
+    * Defines a class that has the same data format as the Level class, to
+    * permit creating the serialized form of a Level instance.
+    */
     private static final class LevelData implements Serializable {
         private static final long serialVersionUID = -8176160795706313070L;
         private final String name;
@@ -89,15 +92,14 @@ public class Levels {
     }
 
     /**
-     * Defines an object output stream that allows the data for one class to be
-     * interpreted as the data for another class.  This class is useful in
-     * creating serialization data for a class when access to an appropriate
-     * constructor is not available.
-     */
+    * Defines an object output stream that allows the data for one class to be
+    * interpreted as the data for another class. This class is useful in
+    * creating serialization data for a class when access to an appropriate
+    * constructor is not available.
+    */
     private static final class ClassReplacingObjectOutputStream extends ObjectOutputStream {
         private final ObjectStreamClass from;
-        private final ObjectStreamClass to;
-
+        private final ObjectStreamClass to; 	
         ClassReplacingObjectOutputStream(OutputStream out, Class from, Class to) throws IOException {
             super(out);
             this.from = ObjectStreamClass.lookup(from);
@@ -113,23 +115,46 @@ public class Levels {
     }
 
     /**
-     * Creates an instance of the Level class.  This method works around the
-     * fact that there is no public constructor for the Level class by
-     * constructing the serialized form for an instance with the specified
-     * field values and deserializing it.
-     */
+    * Creates an instance of the Level class. This method works around the
+    * fact that there is no public constructor for the Level class by
+    * constructing the serialized form for an instance with the specified
+    * field values and deserializing it. 
+    * 
+    * If deserialization fails, it creates a Level with a numerical name that 
+    * can be de-serialised by a remote client that doesn't have
+    * com.sun.jini.logging.Levels bytecode.
+    * 
+    * Local logging code still enjoys the benefit of a meaningful name even
+    * when deserialization fails.
+    * 
+    * See River-416 for details, the serial form of Levels was broken in Java 1.6.0_41.
+    */
     private static Level createLevel(String name, int value, String resourceBundleName) {
+        Level result = null;
         try {
             ByteArrayOutputStream bytes = new ByteArrayOutputStream();
             ObjectOutputStream out = new ClassReplacingObjectOutputStream(bytes, LevelData.class, Level.class);
             out.writeObject(new LevelData(name, value, resourceBundleName));
             out.close();
             ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()));
-            Level result = (Level) in.readObject();
+            result = (Level) in.readObject();
             in.close();
+            // If this suceeds, Level.readResolve has added the new Level to its internal List.
+            
+        } catch (ClassNotFoundException ex) {
+            // Ignore :)
+        } catch (IOException e) {
+            // Ignore :)
+        } finally {
+            if (result == null){
+                final Level withoutName = Level.parse(Integer.valueOf(value).toString());
+                result =  new Level(name, value, resourceBundleName) {
+                    Object writeReplace() throws ObjectStreamException {
+                        return withoutName;
+                    }
+                };
+            }
             return result;
-        } catch (Exception e) {
-            throw new RuntimeException("Unexpected exception", e);
         }
     }
 }