11 Replies Latest reply on Feb 24, 2010 12:55 AM by jayagopi jagadeesan

    byteman does not output transformed files

    jayagopi jagadeesan Newbie

      Hi,

       

      Tried to output the transformed class using the
      system property -Dorg.jboss.byteman.dump.generated.classes=1 -Dorg.jboss.byteman.dump.generated.classes.directory=c:\\temp\\junk, but byteman did not write out anything. In fact, the transformation did not happen at all and the program ran without instrumentation.

       

      If I remove the properties, then everything works fine. It stops working when I introduce these properties mentioned above. I do use the verbose property

      and I can see that instrumentation does happen for the method/class that I specified in the rule. Here is the ouput :

       

      org.jboss.byteman.agent.Transformer : possible trigger for rule readfield version 2 in class fi.tapiola.tita.jay.byteman.Counter

      RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into method inc() void for rule readfield version 2

      org.jboss.byteman.agent.Transformer : inserted trigger for readfield version 2 in class fi.tapiola.tita.jay.byteman.Counter

       

      Here is my rule script :

       

      RULE readfield version 2

      CLASS fi.tapiola.tita.jay.byteman.Counter

      METHOD inc()

      HELPER fi.tapiola.tita.jay.byteman.helpers.JayHelper

      AFTER READ fi.tapiola.tita.jay.byteman.Counter.cnt

      BIND rzv1 : String = "Counter read wait"

      # NOTE: IF condition is mandatory

      IF TRUE

      DO debug("At read wait point: " + rzv1 + ", cnt=" + $this.cnt),

      # wait 20 ms

      waitFor(rzv1, 20)

      ENDRULE

       

      So, tranformation happens, but I do not see any output in c:\temp\junk directory.
      Have I defined the properties ok ? I also tried the value "true" for the system property org.jboss.byteman.dump.generated.classes, but no luck.

       

      cheers,
      jay

        • 1. Re: byteman does not output transformed files
          Andrew Dinn Master

          Hi Jay,

           

          I think this problem may be because you are running on Windows and may well relate to the path you are employing. I normally work on Linux and I have not done any serious testing on Windows so file i/o is one area where it would be quite easy for something to go wrong.

           

          It looks like the transformer is getting called, doing the transform on the bytecode and then getting an exception during the dump of the transformed bytecode. I suspect the file open may well throw an unexpected runtime exception with your path which my code may not catch. This would stop the transformer returning the modified bytecode so the JVM would continue without running any rules.

           

          As an experiment would you try creating a directory called junk in your working directory and set the path using-Dorg.jboss.byteman.dump.generated.classes.directory=junk  If that fails then perhaps you could you leave this variable unset. In the latter case you would need to ensure that the original versions of the classes you are using are not in the working directory because, assuming it actually works this time, the dump will overwrite the original file.

           

          When I get home I will try to do some testing on my own Windows box to see if I can resolve the problem.

          • 2. Re: byteman does not output transformed files
            jayagopi jagadeesan Newbie

            Hi Andrew,

             

            Actually, I have already tried those alternatives, but no luck

            But I appreciate the suggestions. Thanks.

            Please try it on your windows box and let me know.

             

            cheers,

            jay

            • 3. Re: byteman does not output transformed files
              Andrew Dinn Master

              Hi Jay,

               

              I managed to find a windows box at work here and when I ran a test it worked as expected. What I suspect is happening is that the code which is attempting to check the dump directory and open/write the dumped class bytecode file is failing because of a security exception. This is an unchecked runtime exception which does not have to be declared or explicitly caught and, indeed, the dump routine does not attempt to catch such an exception. It can occur either in the call to File.exists which tests that the dump directory is present or under the calls to FileOutputStream.new/write/close which are used to implement the dump itself. My money is on the former but a security exception from any of these would cause the transformer to exit, bypassing rule injection. The JVM does not generate any output for exceptions coming out of the transformer so when this happens it will happen silently, making it difficult to understand.

               

              I will raise a JIRA for the dump code to catch any throwable and handle it by logging a warning message plus the exception stack then returning. This should allow the transformer to continue with rule injection but will let you know that there is a problem. Since the failure to dump the transformed code is not vital to operation of the program this seems a reasonable thing to do.

               

              Meanwhile, could you check the configuration of your installed java runtime to see whether file operations are restricted by your security configuraton. If so, could you also check whether removing these security restructions allows the dump code to operate as expected.

              • 4. Re: byteman does not output transformed files
                jayagopi jagadeesan Newbie

                Hi Andrew,

                 

                Thanks for the helpful insight. Yes, the injection can proceed with a stacktrace and a helpful message to the user as to

                why the file could not be written.

                Seems fair

                I am using the IDE from IBM (RAD v7 ) for developing java applications. All the applications in various projects seem to be able to read/write files

                without any problems. So, it does not look like the problem is with java runtime. However, I could check the JRE security policies etc.

                I am not sure if it could be my F-Secure virus protection/firewall software. Need to check the windows log and F-Secure logs to ascertain this.

                Thanks awfully for all the assistance. Very much appreciated.

                Will get back to you after some investigation.

                 

                cheers,

                jay

                • 5. Re: byteman does not output transformed files
                  jayagopi jagadeesan Newbie

                  Hi Andrew,

                   

                  There were no log entries either in windows eventlog or F-Secure log showing any errors in writing to the file system.

                  However, I was able to make a hierarchy of of directories( <curr.work.dir.>\junk1\junk2 ) and write a text file into dir. junk2 successfully, from within my application ( that uses byteman ).

                  In fact, my application is a standalone java application and is not using any security manager.

                   

                  I also tried to use a security manager and specify an AllPermision user policy file for the application. Even with this configuration I was able to write

                  to the text file.

                  This is the policy I used ( file jay.policy ) :

                  grant {

                     permission java.security.AllPermission;

                  };

                   

                  I ran the application with system properties -Djava.security.manager -Djava.security.policy=jay.policy

                   

                  This is how I write the text file, in my application :

                  new

                   

                   

                  File( "junk1\\junk2").mkdirs();

                  PrintWriter pw =

                  new PrintWriter( new BufferedOutputStream( new FileOutputStream( new File("junk1\\junk2\\crap.txt") ) ) );

                  pw.println(

                  "Sure, I was able to write, buddy" );

                  pw.flush();

                  pw.close();

                   

                  So, I am wondering, how come byteman is unable to make directories and write the class file.

                  Any further enlightening thoughts are most welcome.

                  Thanks for the help, once again.

                   

                  cheers,

                  jay

                  • 6. Re: byteman does not output transformed files
                    Andrew Dinn Master

                    . . .
                    So, I am wondering, how come byteman is unable to make directories and write the class file.

                    Any further enlightening thoughts are most welcome.

                    Thanks for the help, once again.

                     

                    I am a bit baffled by this result. All I can suggest is that you wait for me to patch BYTEMAN-83 in the next release, download it and see whether the dump call catches an exception and printsthe exception stack trace to System.out. Alternatively, if you don't want to wait you can grab an existing  source release, insert the patch it yourself and then rebuild to achieve the same effect. The fix is to enclose the body of Transformer.dumpClass(String, byte[], boolean) in a try catch block as follows

                     

                    private static void dumpClass(String fullName, byte[] bytes, boolean intermediate)
                    {

                        try {

                            <insert original method body here>

                        } catch (Throwable th) {

                            System.out.println("Transformer.dumpClass : unexpected error dumping class " + fullname);

                            th.printStackTrace(System.out);

                        }

                    }

                     

                    It's not normally good form to swallow a Throwable but in this case the JVM will do the same so there is no point propagating it upwards.

                     

                    You will need ant and a java SDK in your path to build a release from source. Execute "ant install" in the top level of the source tree to do the build and, if all goes well, you should find a binary release tree in directory install.

                    • 7. Re: byteman does not output transformed files
                      jayagopi jagadeesan Newbie

                      Hi Andrew,

                       

                      Thanks for the suggestion. I have the source for the latest release 1.2.1. So, I will patch it and try tomorrow.

                      Will let you know what happens

                      Thanks.

                      cheers,

                      jay

                      • 8. Re: byteman does not output transformed files
                        jayagopi jagadeesan Newbie

                        Hi Andrew,

                         

                        I finally got the time to look into this problem again. Sorry for the delay.

                        The problem was the following call in your Transformer#dumpClass() method :

                         

                                 prefix.replaceAll( "\\.", File.separator )

                         

                        This gave a StringIndexOutOfBoundException. The problem is that File.separator is a \ in Windows platform. So, that call won't work in Windows.

                        So, the above call should actually be :

                         

                                 prefix.replaceAll( "\\.", \\\\)

                         

                        in Windows.

                         

                        So, I tried the following and it worked :

                         

                        String dir = null;
                        if ( osname.startsWith( "Win") ) {
                                  dir = dumpGeneratedClassesDir + File.separator + prefix.replaceAll("\\.", "\\\\");
                        }
                        else {
                           dir = dumpGeneratedClassesDir + File.separator + prefix.replaceAll("\\.", File.separator);
                        }

                         

                        Perhaps you have a better solution.

                        Anyway, this is something for you to think about for your next release.

                         

                        cheers,

                        jay

                        • 9. Re: byteman does not output transformed files
                          Andrew Dinn Master

                          jayagopi wrote:

                           

                          Hi Andrew,

                           

                          I finally got the time to look into this problem again. Sorry for the delay.

                          The problem was the following call in your Transformer#dumpClass() method :

                           

                                   prefix.replaceAll( "\\.", File.separator )

                           

                          This gave a StringIndexOutOfBoundException. The problem is that File.separator is a \ in Windows platform. So, that call won't work in Windows.

                           

                          Hmm, yes.  Serves me right for using the regexp based replacement when all I want to do is a character replacement. I think what is needed is the following

                           

                          prefix.replace('.', File.separatorChar);


                          Thaks for letting me know what the problem was.

                           

                          regards,

                           

                           

                          Andrew Dinn

                          • 10. Re: byteman does not output transformed files
                            Andrew Dinn Master

                            Hi Jay,

                             

                            This is fixed in trunk and wll go into the 1.3.0 release. See BYTEMAN-87

                            • 11. Re: byteman does not output transformed files
                              jayagopi jagadeesan Newbie

                              Hi Andrew,

                               

                              Thanks for the fix.

                              Will wait for the release of 1.3.0.

                              cheers,

                              jay