1 Reply Latest reply on Apr 18, 2007 1:11 PM by Chip Schoch

    Separate log files no longer works with JBM 3.2

    Chip Schoch Novice

      When I upgraded to JBM 3.2 recently I had to go back and add:

       <loader-repository>jboss.messaging:loader=ScopedLoaderRepository
       <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
       </loader-repository>


      to my jboss-service.xml files on the message processing MBeans I have written, because when I didn't have it I get:

      2007-04-17 16:07:17,213 ERROR [com.eLynx.Messaging.MessageReceiver] Exception running MessageReceiver [thread id=155].
      tried to access class org.jboss.aop.ClassAdvisor$1 from class org.jboss.aop.ClassAdvisor
      java.lang.IllegalAccessError: tried to access class org.jboss.aop.ClassAdvisor$1 from class org.jboss.aop.ClassAdvisor
       at org.jboss.aop.ClassAdvisor.attachClass(ClassAdvisor.java:271)
       at org.jboss.aop.AspectManager.initialiseClassAdvisor(AspectManager.java:590)
       at org.jboss.aop.AspectManager.getAdvisor(AspectManager.java:578)
       at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.<clinit>(ClientConnectionFactoryDelegate.java)
       at sun.misc.Unsafe.ensureClassInitialized(Native Method)
       at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:25)
       at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:122)
       at java.lang.reflect.Field.acquireFieldAccessor(Field.java:917)
       at java.lang.reflect.Field.getFieldAccessor(Field.java:898)
       at java.lang.reflect.Field.getLong(Field.java:527)
       at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1586)
       at java.io.ObjectStreamClass.access$700(ObjectStreamClass.java:52)
       at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:408)
       at java.security.AccessController.doPrivileged(Native Method)
       at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:400)
       at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:297)
       at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:531)
       at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1552)
       at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1699)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
       at java.rmi.MarshalledObject.get(MarshalledObject.java:135)
       at org.jnp.interfaces.MarshalledValuePair.get(MarshalledValuePair.java:72)
       at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:653)
       at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:588)
       at javax.naming.InitialContext.lookup(InitialContext.java:351)
       at com.eLynx.Messaging.MessageReceiver.run(MessageReceiver.java:547)


      I have my log4j.xml configured to log to different files using the TCLFilter:

      <filter class="org.jboss.logging.filter.TCLFilter">
       <param name="AcceptOnMatch" value="true"/>
       <param name="DeployURL" value="eLynxFileConversion.sar"/>
       </filter>


      Now I do not get any logging to the separate file. It looks like the TCLFilter must be using class loader to determine which archive a class came from? Anyway, it is an unintended consequence of the latest changes.

      Any ideas about how to fix this?

        • 1. Re: Separate log files no longer works with JBM 3.2
          Chip Schoch Novice

          Judging by the tremendous number of replies I see that this is a topic of enormous interest. However, if anyone is interested I was able to effect a work around by adding another filter. Here it is in case anyone is interested. It should be placed in the chain before the TCLFilter:

          package your.package;
          
          
          
          import java.security.CodeSource;
          import java.security.ProtectionDomain;
          
          import org.apache.log4j.spi.Filter;
          import org.apache.log4j.spi.LoggingEvent;
          
          /**
           * Class CSFilter<br>
           * An appender filter that evaluates log events to see if the class
           * that is specified by the loggerName has a code source that contains
           * the string specified in deployURL.<br><br>
           *
           * It is important that the logger be initialized with a class:<br>
           * Logger logger = Logger.getInstance(MyClass.class);<br><br>
           *
           * This way the loggerName will be a fully qualified class name. This filter
           * uses the thread context classloader to load the class and then obtains the
           * CodeSource via the ProtectionDomain. It checks the path of the code source
           * to see if the url specified in deployURL is contained in it. Therefore it is
           * case sensitive. This class should be used in conjunction with the TCLFilter and should
           * preced it in the chain because if a match is not found this filter returns NEUTRAL.<br><br>
           *
           * The acceptOnMatch parameter is only applied when a match is found. If it is true then a match
           * returns ACCEPT otherwise when it is false a match returns DENY.
           */
          
          public class CSFilter extends Filter
          {
          
           /** The deployment URL string fragment to match against */
          
           private String deployURL;
          
           /** Whether a match should return ACCEPT or DENY */
          
           private boolean acceptOnMatch = true;
          
           /**
           * Method: decide
           *
           *
           * @param event
           *
           * @return
           */
          
           @Override public int decide (LoggingEvent event)
           {
           int result = Filter.NEUTRAL;
          
           if (isMatchingCS (event))
           result = acceptOnMatch ? Filter.ACCEPT : Filter.DENY;
          
           return result;
           }
          
           /**
           * Method: getDeployURL
           *
           *
           * @return
           */
          
           public String getDeployURL ()
           {
           return deployURL;
           }
          
           /**
           * Method: isAcceptOnMatch
           *
           *
           * @return
           */
          
           public boolean isAcceptOnMatch ()
           {
           return acceptOnMatch;
           }
          
           /**
           * Method: isMatchingCS
           *
           *
           * @param event
           *
           * @return
           */
          
           private boolean isMatchingCS (LoggingEvent event)
           {
           boolean match = false;
           try
           {
           ClassLoader cl = Thread.currentThread ().getContextClassLoader ();
           Class clazz = cl.loadClass (event.getLoggerName ());
          
           ProtectionDomain pd = clazz.getProtectionDomain ();
           CodeSource clazzCS = pd.getCodeSource ();
          
           if (clazzCS != null)
           {
           String path = clazzCS.getLocation ().getPath ();
           match = path.contains (deployURL);
           }
           }
           catch (Exception e)
           {
           // Not much to do in this event
           }
          
           return match;
           }
          
           /**
           * Method: setAcceptOnMatch
           *
           *
           * @param acceptOnMatch
           */
          
           public void setAcceptOnMatch (boolean acceptOnMatch)
           {
           this.acceptOnMatch = acceptOnMatch;
           }
          
           /**
           * Method: setDeployURL
           *
           *
           * @param deployURL
           */
          
           public void setDeployURL (String deployURL)
           {
           this.deployURL = deployURL;
           }
          }
          


          Example from log4j.xml

          <filter class="your.package.CSFilter">
           <param name="AcceptOnMatch" value="true"/>
           <param name="DeployURL" value="YourService.sar"/>
           </filter>
           <filter class="org.jboss.logging.filter.TCLFilter">
           <param name="AcceptOnMatch" value="true"/>
           <param name="DeployURL" value="YourService.sar"/>
           </filter>