1 2 3 Previous Next 40 Replies Latest reply on Oct 14, 2013 10:38 PM by Ronald Sigal Go to original post
      • 15. Re: Re: Re: Re: Skipping code with Byteman?
        Ronald Sigal Master

        Well, I changed the Bind section to

        BIND

        config:org.hibernate.validator.HibernateValidatorConfiguration = javax.validation.Validation.byProvider(HibernateValidator.class).configure();

        tmp:javax.validation.ValidatorFactory = config.buildValidatorFactory();

        and I got

        stdOut: Rule.ensureTypeCheckedCompiled : error type checking rule after write validatorFactory 1

        stdOut: org.jboss.byteman.rule.exception.TypeException: FieldExpression.typeCheck : invalid path HibernateValidator to static field class file src/test/resources/validation.btm line 32

        stdOut:     at org.jboss.byteman.rule.expression.FieldExpression.checkIndirectStatic(FieldExpression.java:148)

        stdOut:     at org.jboss.byteman.rule.expression.FieldExpression.typeCheck(FieldExpression.java:106)

        stdOut:     at org.jboss.byteman.rule.expression.MethodExpression.findMethod(MethodExpression.java:278)

        stdOut:     at org.jboss.byteman.rule.expression.MethodExpression.typeCheck(MethodExpression.java:173)

        stdOut:     at org.jboss.byteman.rule.expression.MethodExpression.typeCheck(MethodExpression.java:168)

        stdOut:     at org.jboss.byteman.rule.binding.Binding.typeCheck(Binding.java:131)

        stdOut:     at org.jboss.byteman.rule.Event.typeCheck(Event.java:114)

        stdOut:     at org.jboss.byteman.rule.Event.typeCheck(Event.java:106)

        stdOut:     at org.jboss.byteman.rule.Rule.typeCheck(Rule.java:521)

        stdOut:     at org.jboss.byteman.rule.Rule.ensureTypeCheckedCompiled(Rule.java:449)

        stdOut:     at org.jboss.byteman.rule.Rule.execute(Rule.java:672)

        stdOut:     at org.jboss.byteman.rule.Rule.execute(Rule.java:653)

        stdOut:     at org.jboss.resteasy.plugins.validation.ValidatorContextResolver.getValidatorFactory(ValidatorContextResolver.java:65)

        where

         

        config:org.hibernate.validator.HibernateValidatorConfiguration = javax.validation.Validation.byProvider(HibernateValidator.class).configure();

        is line 32.

         

        Then I added the package name to HibernateValidator:

         

        BIND

        config:org.hibernate.validator.HibernateValidatorConfiguration = javax.validation.Validation.byProvider(org.hibernate.validator.HibernateValidator.class).configure();

        tmp:javax.validation.ValidatorFactory = config.buildValidatorFactory();

         

        and got

         

        stdOut: Rule.ensureTypeCheckedCompiled : error type checking rule after write validatorFactory 1

        stdOut: org.jboss.byteman.rule.exception.TypeException: StaticExpression.typeCheck : invalid field name class file src/test/resources/validation.btm line 32

        stdOut:     at org.jboss.byteman.rule.expression.StaticExpression.typeCheckAny(StaticExpression.java:109)

        stdOut:     at org.jboss.byteman.rule.expression.StaticExpression.typeCheck(StaticExpression.java:78)

        stdOut:     at org.jboss.byteman.rule.expression.FieldExpression.typeCheck(FieldExpression.java:109)

        stdOut:     at org.jboss.byteman.rule.expression.MethodExpression.findMethod(MethodExpression.java:278)

        stdOut:     at org.jboss.byteman.rule.expression.MethodExpression.typeCheck(MethodExpression.java:173)

        stdOut:     at org.jboss.byteman.rule.expression.MethodExpression.typeCheck(MethodExpression.java:168)

        stdOut:     at org.jboss.byteman.rule.binding.Binding.typeCheck(Binding.java:131)

        stdOut:     at org.jboss.byteman.rule.Event.typeCheck(Event.java:114)

        stdOut:     at org.jboss.byteman.rule.Event.typeCheck(Event.java:106)

        stdOut:     at org.jboss.byteman.rule.Rule.typeCheck(Rule.java:521)

        stdOut:     at org.jboss.byteman.rule.Rule.ensureTypeCheckedCompiled(Rule.java:449)

        stdOut:     at org.jboss.byteman.rule.Rule.execute(Rule.java:672)

        stdOut:     at org.jboss.byteman.rule.Rule.execute(Rule.java:653)

        stdOut:     at org.jboss.resteasy.plugins.validation.ValidatorContextResolver.getValidatorFactory(ValidatorContextResolver.java:65)

         

         

         

        I think maybe I should hand in my union card and apply at McDonalds.

        • 16. Re: Re: Re: Re: Re: Skipping code with Byteman?
          Andrew Dinn Master

          Then I added the package name to HibernateValidator:

           

          BIND

          config:org.hibernate.validator.HibernateValidatorConfiguration = javax.validation.Validation.byProvider(org.hibernate.validator.HibernateValidator.class).configure();

          tmp:javax.validation.ValidatorFactory = config.buildValidatorFactory();

           

          and got

           

          stdOut: Rule.ensureTypeCheckedCompiled : error type checking rule after write validatorFactory 1

          stdOut: org.jboss.byteman.rule.exception.TypeException: StaticExpression.typeCheck : invalid field name class file src/test/resources/validation.btm line 32

          . . .

           

           

          I think maybe I should hand in my union card and apply at McDonalds.

           

          On the contrary. You have now assembled all the pieces of the puzzle and found that there is a gaping hole. Please accept a Byteman badge of honour with pride. The error message says it all:

           . . . invalid field name class . . .

           

          albeit that a pair of quotes would make it a lot clearer

           

          . . . invalid field name "class" . . .

           

          Byteman's parser thinks "class" names a static field of HibernateValidator whereas what you are trying to do is refer to the Class instance HibernateValidator.class. Byteman does not yet understand the syntax for Class instance literals. This merits the grand triple prize of a JIRA, a fix in the next release and an honourable mention in dispatches (well, ok, how about the release notes).

           

          As a workaround would you be able to create an instance and fetch the class from it? i.e. change the call to

          Validation.byProvider(new org.hibernate.validator.HibernateValidator().getClass()).configure

          That's assuming there is an easily available constructor as above.

           

          I am sorry for leading you this far only to not provide a full solution. All the same, thank you very much for persevering with this and for getting far enough to find this error.

          • 18. Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
            Ronald Sigal Master

            Thank you, Andrew.  You made my day. 

             

            I'm trying to take your suggestion, but I'm having trouble.  The rule is now

            RULE after write validatorFactory 1

            CLASS ValidatorContextResolver

            METHOD getValidatorFactory

            AFTER WRITE validatorFactory 1

            BIND

            validator:org.hibernate.validator.HibernateValidator = new org.hibernate.validator.HibernateValidator();

            config:org.hibernate.validator.HibernateValidatorConfiguration = javax.validation.Validation.byProvider(validator.getClass()).configure();

            tmp:javax.validation.ValidatorFactory = config.buildValidatorFactory();

            IF TRUE

            DO

            traceln("bm: wrote validatorFactory: no exception");

            validatorFactory = tmp

            traceln("bm: set default ValidatorFactory");

            ENDRULE

            If I comment out the line "validatorFactory = tmp", I get the two traceln messages, but if I uncomment, I don't, so I guess there's something wrong with the rule.  But I put

             

                          org.hibernate.validator.HibernateValidator v= new HibernateValidator();
                          org.hibernate.validator.HibernateValidatorConfiguration c = javax.validation.Validation.byProvider(v.getClass()).configure();
                          javax.validation.ValidatorFactory tmp = c.buildValidatorFactory();
                          System.out.println("tmp: " + tmp);

             

            in the code and it runs fine. Is there a way to get more verbose output from Byteman to get an idea what it's thinking?

            • 19. Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
              Andrew Dinn Master

              Hi Ron,

              If I comment out the line "validatorFactory = tmp", I get the two traceln messages, but if I uncomment, I don't, so I guess there's something wrong with the rule.  But I put

               

                            org.hibernate.validator.HibernateValidator v= new HibernateValidator();
                            org.hibernate.validator.HibernateValidatorConfiguration c = javax.validation.Validation.byProvider(v.getClass()).configure();
                            javax.validation.ValidatorFactory tmp = c.buildValidatorFactory();
                            System.out.println("tmp: " + tmp);

               

              in the code and it runs fine. Is there a way to get more verbose output from Byteman to get an idea what it's thinking?

               

              I think I know what is wrong. Your line

              validatorFactory = tmp;

               

              appears to be referring to a field of $0. So, I think you need to write

               

              $0.validatoractory = tmp;

               

              As for how you would check that this is the problem (apart from just rewriting the rule and seeing what happens) there are 3 things you can do. Here they are in ascending order of preference:

               

              1) You can set -Dorg.jboss.byteman.verbose in the JVM which the rules are going to be injected into. This will make Byteman print a whole lot of trace detailing it's attempts to inject, type check and execute rules. Output goes to the System.out and/or System.err of the JVM running Byteman. In amongst the screeds of output you ought to see either confirmation that the rule has been injected or a parse or type error explaining why it has not worked.

               

              2) You can use script bmcheck provided in the Byteman download to run an offline check of your rules against the application code base. bmcheck will notify you of any parse or type errors it finds, tell you if it failed to find a class or method to match some given rule and (very) occasionally tell you it cannot fully check a rule. You  need to provide bmcheck with (one or more)  -cp arguments to point bmcheck at the directories or jars containing classes mentioned in your rules (each -cp argumetn is followed by a path to a jar or the root of a class tree). Also, if your CLASS clauses omit the package name for the target class then you need to provide (one or more) -p arguments to tell Byteman which package(s) the target classes actually belong to (it normally matches names as classes are loaded but it cannot do that offline since nothing will be loading them).

               

              3) You can use Byteman's maven rulecheck plugin to type check your rules automatically as part of your maven build. Essentiall, it runs bmcheck for you using your test dependencies to supply the required jars. You stlll may need to configure package names for target classes (in the plugin conf). Details of how to use it are provided in Byteman tutorial #3 which is linked off the Byteman documentation page.

               

              Special hint: you want to use option 3 :-)

              • 20. Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                Ronald Sigal Master

                Achhh.  D'oh!  You're right.  And, it gets worse.  I omitted the semicolon after "validatorFactory = tmp".

                 

                So, everything old is new again.  It's just like when I was in graduate school.  An hour turnaround to find out I left out a semicolon.  ;-)

                 

                I used option 3.  It's great!!

                 

                I'm going to revisit the problem I mentioned in comment 6, but I'm well ahead of where I was a few days ago.  Thank you, Andrew!!

                • 21. Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                  Ronald Sigal Master

                  Ok, I've gone back to that other problem.  The relevant code is

                     protected void convertFromString(String stringRep)

                     {

                        InputStream is = new ByteArrayInputStream(stringRep.getBytes());

                        BufferedReader br = new BufferedReader(new InputStreamReader(is));

                        String line;

                        try

                        {

                           int index = 0;

                           line = br.readLine();

                           ...

                   

                  When I use

                   

                     @BMRule(name="ResteasyViolationException.convertFromString_unableToParseResteasyViolationException",

                           targetClass="ResteasyViolationException",

                           targetMethod="convertFromString",

                           targetLocation="AFTER WRITE $line",

                           action="traceln(\"bm local: index = \" + $index); $index = 17; traceln(\"bm local: index = \" + $index);")

                   

                  there's no problem, and when I change the action to

                  action="traceln(\"bm local: line = \" + $line);"

                   

                  there's no problem, but when I change the action to

                  action="traceln(\"bm local: line = \" + $line); $line = \"xyz\"; traceln(\"bm local: line = \" + $line);")

                  I get

                   

                  java.lang.VerifyError: (class: org/jboss/resteasy/api/validation/ResteasyViolationException, method: convertFromString signature: (Ljava/lang/String;)V) Incompatible argument to function

                      at org.jboss.resteasy.test.nextgen.validation.TestValidationI18NLocal.doResteasyViolationException_convertFromString_unableToParseResteasyViolationException(TestValidationI18NLocal.java:146)

                      at org.jboss.resteasy.test.nextgen.validation.TestValidationI18NLocal.resteasyViolationException_convertFromString_unableToParseResteasyViolationException(TestValidationI18NLocal.java:116)

                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                      at java.lang.reflect.Method.invoke(Method.java:606)

                      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)

                      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)

                      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)

                      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)

                      at org.jboss.byteman.contrib.bmunit.BMUnitRunner$8.evaluate(BMUnitRunner.java:346)

                      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)

                      at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)

                      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)

                      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)

                      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)

                      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)

                      at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)

                      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)

                      at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)

                      at org.junit.runners.ParentRunner.run(ParentRunner.java:220)

                      at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)

                      at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)

                      at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:165)

                      at org.apache.maven.surefire.Surefire.run(Surefire.java:107)

                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                      at java.lang.reflect.Method.invoke(Method.java:606)

                      at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:289)

                      at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1005)

                  Exception in thread "Thread-0" java.lang.InternalError

                      at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)

                      at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)

                      at org.jboss.byteman.agent.Retransformer.removeScripts(Retransformer.java:292)

                      at org.jboss.byteman.agent.TransformListener.handleScripts(TransformListener.java:335)

                      at org.jboss.byteman.agent.TransformListener.deleteScripts(TransformListener.java:290)

                      at org.jboss.byteman.agent.TransformListener.handleConnection(TransformListener.java:215)

                      at org.jboss.byteman.agent.TransformListener.run(TransformListener.java:146)

                  ^CDestroying 1 processes

                   

                  and then it hangs.  This is strange, because line 146 of TestValidationI18NLocal is

                  new ResteasyViolationException("abc");

                  and the ResteasyViolationException constructor is

                     public ResteasyViolationException(String stringRep)

                     {

                        convertFromString(stringRep);

                     }

                  By the way, I'm still running the maven rulecheck plugin, and it's not complaining.

                  • 22. Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                    Andrew Dinn Master

                    HI Ron,

                    when I change the action to

                    action="traceln(\"bm local: line = \" + $line); $line = \"xyz\"; traceln(\"bm local: line = \" + $line);")

                    I get

                     

                    java.lang.VerifyError: (class: org/jboss/resteasy/api/validation/ResteasyViolationException, method: convertFromString signature: (Ljava/lang/String;)V) Incompatible argument to function

                        at org.jboss.resteasy.test.nextgen.validation.TestValidationI18NLocal.doResteasyViolationException_convertFromString_unableToParseResteasyViolationException(TestValidationI18NLocal.java:146)

                         at

                    . . .

                     

                    Well, the verifier obviously does not like the bytecode generated by Byteman. But it must be transforming the class and injecting code or else you would not get the error and the maven plugin would be complaining. So, the problem does not appear to lie in your rule.

                     

                    The best way to find out why the verifier is rejecting the code is to get Byteman to write the transformed bytecode to a file and then use javap to eyeball it. Could you run the failing rule with system property -Dorg.jboss.byteman.dump.generated.classes set in your JVM. This should generate a .class file for class ResteasyViolationException containing the injected code. If you attach the file I will print it out and see if I can work out what is wrong with the bytecode.

                    • 23. Re: Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                      Ronald Sigal Master

                      I'm attaching esteasyViolationException.jvmbytes.  Thanks, Andrew.

                      • 24. Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                        Andrew Dinn Master

                        Hi Ron,

                         

                        Thanks for the bytecode dump. It has identified the actual problem.

                         

                        Here is the relevant bit of injected bytecode:

                         

                              43: aload         4
                              45: invokevirtual #198                // Method java/io/BufferedReader.readLine:()Ljava/lang/String;
                              48: astore        5
                              50: ldc           #200                // String ResteasyViolationException.convertFromString()_2
                              52: aload_0     
                              53: iconst_1    
                              54: anewarray     #202                // class java/lang/Object
                              57: dup_x2      
                              58: dup         
                              59: iconst_0    
                              60: aload         5
                              62: aastore     
                              63: invokestatic  #208                // Method org/jboss/byteman/rule/Rule.execute:(Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V
                              66: iconst_0    
                              67: aaload      
                              68: checkcast     #2                  // class org/jboss/resteasy/api/validation/ResteasyViolationException
                              71: astore        5
                              73: getstatic     #167                // Field java/lang/System.out:Ljava/io/PrintStream;
                              76: new           #216                // class java/lang/StringBuilder
                              79: dup         
                              80: invokespecial #217                // Method java/lang/StringBuilder."":()V
                              83: ldc           #219                // String line:
                              85: invokevirtual #222                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                              88: aload         5
                              90: invokevirtual #222                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                              93: invokevirtual #223                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                              96: invokevirtual #174                // Method java/io/PrintStream.println:(Ljava/lang/String;)V
                        

                         

                        The write to local var line happens at bytecode 48. After that bytecodes 50 to 62 set up the rule execute call.

                         

                        Bytecode 50 loads the String lookup key "ResteasyViolationException.convertFromString()_2" which  identifies the rule to be run. Bytecode 52 loads the second argument to execute, this. Bytecode 54 creates an Object array of size 1 which it duplicates pushing the copy below the key and this. So, the Java stack now contains [... Object[], String, ResteasyViolationException, Object[] ] i.e. a saved copy of the Object array (we will see why we need this later) and then the arguments needed for the execute call (key, this, extra args array).

                         

                        The only this left to do is fill in the extra args array. Bytecodes 58 to 60 copy the array, stack constant 0, load the line we wrote to slot 5 onto the stack and then the aastore at 62 writes the line into the object array at offset 0, removing the 3 elements just stacked.

                         

                        The call at bytecode 63 removes the 3 arguments reducing the stack from [... Object[], String, ResteasyViolationException, Object[] ] to [... Object[] [ i..e leaving the arguments array on the stack. The reason we made this extra copy is that your rule updates $line. The rule code installs the updated value for $line in the extra args array. So, the code which follows the execute call is meant to pull this value out and write it into the relevant local var slot. That's why we carefully pushed the Object[] onto the stack before the call arguments. It is needed to unpack modified values.

                         

                        Your rule only updates one local variable so the unpack can just read the array entry and then drop the array. So, bytecode 66 stacks index 0 and bytecode 67 loads element 0 popping the index and the Object[]. Now this is an Object[] but we know element 0 is a String. So, the code needs to cast the returned value to String before writing it to local var slot 5. The bytecode verifier knows that this is the correct type for that slot at this point in the method. Clearly, Byteman has got this wrong because it has planted a checkast for class ResteasyViolationException followed by the astore to slot 5.

                         

                        I'll raise a JIRA for this then see if I can work out what is going wrong. I suspect it's just a simple error in the way the injection routine is looking the type associated with the slot. Thanks very much for persevering far enough to find this bug.

                         

                        regards,

                         

                         

                        Andrew DInn

                        • 26. Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                          Ronald Sigal Master

                          Oh, cool.

                           

                          [SEE COMMENT #29 FOR AN EXPLANATION OF THE PROBLEM DESCRIBED IN THIS COMMENT.  MY MISTAKE.]

                           

                          On to the next problem, if I may.  In

                           

                          public class ConstraintTypeUtil11 implements ConstraintTypeUtil

                          {

                             public ConstraintType.Type getConstraintType(Object o)

                             {

                                ...

                                ConstraintViolation<?> v = ConstraintViolation.class.cast(o);

                                Iterator<Node> nodes = v.getPropertyPath().iterator();

                                Node firstNode = nodes.next();

                                if (firstNode.getKind() == ElementKind.METHOD)

                           

                          I want the call to firstNode.getKind() to return ElementKind.METHOD . My rule is

                           

                             @BMRule(name="constraintTypeUtil11_getConstraintType_unexpectedPathNode",

                                   targetClass="org.jboss.resteasy.plugins.validation.ConstraintTypeUtil11",

                                   targetMethod="getConstraintType",

                                   targetLocation = "AT INVOKE ^javax.validation.Path$Node.getKind",

                          //         targetLocation="AT INVOKE org.hibernate.validator.internal.engine.path.NodeImpl.getKind ALL",  // Also tried this

                          //         targetLocation = "AT INVOKE getKind",                                                                                             // and this

                                   action="trace(\"returning METHOD\"); RETURN javax.validation.ElementKind.METHOD;")

                          and nothing happens, which I've verified by stepping through with a debugger.  Could the nested class be a problem?

                           

                          Thanks, as always.

                          • 27. Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                            Ronald Sigal Master

                            [SEE COMMENT #30 FOR AN EXPLANATION OF THE PROBLEM DESCRIBED IN THIS COMMENT.  MY MISTAKE.]

                             

                            Got another question.  My junit test is

                             

                               @BMRule(name="validatorContextResolver_getContext_unableToLoadValidationSupport",

                                     targetClass="org.jboss.resteasy.plugins.validation.ValidatorContextResolver",

                                     targetMethod="getContext",

                                     targetLocation="AT INVOKE configure",

                                    action="THROW new Exception();")

                               @Test

                               public void validatorContextResolver_getContext_unableToLoadValidationSupport() throws Exception

                               {

                                  ...

                                  try

                                  {

                                     new ValidatorContextResolver().getContext(null);  // line 230

                                     fail();

                                  }

                                  catch (RuntimeException e)

                                  {

                             

                            where ValidatorContextResolver().getContext() is

                             

                               public GeneralValidator getContext(Class<?> type) {

                                  try

                                  {

                                     Configuration<?> config = Validation.byDefaultProvider().configure();

                                     ...

                                  }

                                  catch (Exception e)

                            and I get

                             

                            Rule.ensureTypeCheckedCompiled : error type checking rule validatorContextResolver_getContext_unableToLoadValidationSupport

                            org.jboss.byteman.rule.exception.TypeException: ThrowExpression.typeCheck : exception type not declared by trigger method Exception file org.jboss.resteasy.test.nextgen.validation.TestValidationI18NLocal_en_US+validatorContextResolver_getContext_unableToLoadValidationSupport line 7

                                at org.jboss.byteman.rule.expression.ThrowExpression.checkThrownTypeIsValid(ThrowExpression.java:427)

                                at org.jboss.byteman.rule.expression.ThrowExpression.typeCheck(ThrowExpression.java:176)

                                at org.jboss.byteman.rule.Action.typeCheck(Action.java:106)

                                at org.jboss.byteman.rule.Rule.typeCheck(Rule.java:523)

                                at org.jboss.byteman.rule.Rule.ensureTypeCheckedCompiled(Rule.java:449)

                                at org.jboss.byteman.rule.Rule.execute(Rule.java:672)

                                at org.jboss.byteman.rule.Rule.execute(Rule.java:653)

                                at org.jboss.resteasy.plugins.validation.ValidatorContextResolver.getContext(ValidatorContextResolver.java:114)

                                at org.jboss.resteasy.test.nextgen.validation.TestValidationI18NLocal.validatorContextResolver_getContext_unableToLoadValidationSupport(TestValidationI18NLocal.java:230)

                                ...

                            It seems that Byteman is ignoring the try / catch in ValidatorContextResolver().getContext().  If I change the action to "THROW new RuntimeException()" it works fine ...

                            • 28. Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                              Ronald Sigal Master

                              Follow up to the previous note.  The catch clause in ValidatorContextResolver().getContext() is

                               

                              catch (Exception e)
                              {
                                 throw new ValidationException("Unable to load Validation support", e);
                              }

                               

                              and, instead of getting the exception I expect (with the action clause changed to "THROW new RuntimeException();"), I'm getting a RuntimeException with no message.  When I changed the catch clause to

                               

                              catch (Exception e)
                              {
                                 e.printStackTrace();
                                 System.out.println("e: " + e);
                                 RuntimeException e1 = Exceptions.EXCEPTIONS.unableToLoadValidationSupport(e);
                                 System.out.println("e: " + e);
                                 System.out.println("e1: " + e);
                                 throw e1;
                              }

                              and stepped through it in a debugger, control went directly to throw e1 ...  I'm attaching the bytecode for ValidatorContextResolver.

                               

                              Just tried something else.  I changed the action clause to "THROW new RuntimeException(\"bm\");", and that's what I catch in the junit test, instead of Exceptions.EXCEPTIONS.unableToLoadValidationSupport(e).

                              • 29. Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Re: Skipping code with Byteman?
                                Ronald Sigal Master

                                Re: comment #26

                                 

                                That was just a dumb Byteman programming mistake.  The BMUnit rule should have been

                                   @BMRule(name="constraintTypeUtil11_getConstraintType_unexpectedPathNode",

                                         targetClass="org.hibernate.validator.internal.engine.path.NodeImpl",

                                         targetMethod="getKind",

                                         targetLocation="AT ENTRY",

                                         action="trace(\"returning METHOD\"); RETURN javax.validation.ElementKind.METHOD;")

                                I was applying the rule to the wrong class.