1 Reply Latest reply on Feb 17, 2015 7:06 AM by Andrew Dinn

    typeCheck Error - Help needed

    Hari Kandasamy Newbie

      I'm new to byteman. So far impressed with it. Right now using it test some failover scenarios. I have a rule like below for simulating a LDAP failure from spring security.

       

      RULE error ldap entry failover

      CLASS ^org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider

      METHOD searchForUser

      AT ENTRY

      IF true

      DO traceln("Byteman detected you are entering searchForUser method");

         THROW org.springframework.ldap.ServiceUnavailableException(new javax.naming.ServiceUnavailableException("byteman says ldap service unavailable in doAuthentication"))

      ENDRULE

      This is not compiling with the below error

      Rule.ensureTypeCheckedCompiled : error type checking rule error ldap entry failover

      org.jboss.byteman.rule.exception.TypeException: NewExpression.typeCheck : unknown type javax.naming.ServiceUnavailableException file /home/hkandasa/ldapfailover.btm line 15

       

      I've setup a byteman listener in java opts and wants to inject rules at runtime. How should I make this work ? Can someone redirect me in the right direction

        • 1. Re: typeCheck Error - Help needed
          Andrew Dinn Master

          Hi Hari,

          I'm new to byteman. So far impressed with it.

          Thanks for trying it out.

           

          I have a rule like below for simulating a LDAP failure from spring security.

          RULE error ldap entry failover

          . . .

          This is not compiling with the below error

          Rule.ensureTypeCheckedCompiled : error type checking rule error ldap entry failover

          org.jboss.byteman.rule.exception.TypeException: NewExpression.typeCheck : unknown type javax.naming.ServiceUnavailableException file /home/hkandasa/ldapfailover.btm line 15

          You will have to tell me a little bit more about how your application is working in order for me to give yo a definite answer here. In particular, are you running your application using JBoss EAP or OSGi? Also, just for completeness, what version of Byteman and what version of Java are you using?

           

          I'll try to suggest a few things you might consider before you can provide me with these exact details. The problem appears to be to do with visibility of class ServiceUnavailableException. When Byteman attempts to inject rule code into a trigger class (such as the Spring Framework class ActiveDirectoryLdapAuthenticationProvider mentioned by your rule)  it uses the classloader of that trigger class to lookup any other classes named in the rule. So, the error means that the classloader which has loaded the Spring framework classes is not able to locate the ServiceUnavailableException class.

           

          Now ServiceUnavailableException is one of the Java bootstrap classes (it can be found in the java runtime jar file rt.jar located in dir jre/lib). In a standard Java SE program every classloader is able to resolve references to bootstrap classes. However, this is not always true when you use an application server such as EAP or an OSGi-based program or, indeed, any other module based application framework which uses its own special classloader organization to control loading and visibility of classes. Module system classloaders normally load classes for a specific set of packages from their own jars and by default fail to resolve references to  classes not belonging to those packages. They are usually configured to forward references to packages outside that set  to other module loaders and, in a few cases they may also know about some of the packages managed by the system or bootstrap loader and be willing to forward load requests for those packages. However, that is not the default behaviour.

           

          In fact, this is a problem for Byteman itself. The code Byteman injects needs to be able to refer to a few Byteman classes, 3 exception classes and class Rule.  That has to work from any classloader if Byteman is to be able =to inject into any class. So, for example, when using Byteman with JBoss EAP a special workaround is used to ensure that these classes are visible to all loaders. The startup script for JBoss EAP adds

           

          -Djboss.modules.system.pkgs=org.jboss.byteman

           

          to the java command line. The EAP loaders in JBoss Modules  recognise this property setting. They interpret it as a list of packages which should be resolved by forwarding the lookup/load request to the system loader (which will also forward to the bootstrap loader if needed). So, if you are using JBoss EAP thne one way to get your rule to work is to modify the command line setting to

          -Djboss.modules.system.pkgs=org.jboss.byteman,javax.naming 

          This will make the javax.naming classes visible in all classloaders which means that Byteman can locate it and inject code which refers to it. It is unlikely but, of course, making this package globally visible might possibly cause a problem for other parts of your application.

           

          A similar workaround is available for OSGi-based deployments. See the following issue for details

           

              [BYTEMAN-273] Support for Apache Karaf / JBoss Fuse - JBoss Issue Tracker

           

          regards,

           

           

          Andrew Dinn