{"id":544,"date":"2011-09-21T08:32:00","date_gmt":"2011-09-21T08:32:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/practical-introduction-into-code-injection-with-aspectj-javassist-and-java-proxy.html"},"modified":"2012-10-21T20:13:18","modified_gmt":"2012-10-21T20:13:18","slug":"practical-introduction-into-code","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html","title":{"rendered":"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially to troubleshooting problems in third-party libraries without source codes or in an environment where it isn\u2019t possible to use a debugger or a profiler. Code injection is also useful for dealing with concerns that cut across the whole application, such as performance monitoring. Using code injection in this way became popular under the name <a href=\"http:\/\/en.wikipedia.org\/wiki\/Aspect-oriented_programming\">Aspect-Oriented Programming<\/a> (AOP). Code injection isn\u2019t something used only rarely as you might think, quite the contrary; every programmer will come into a situation where this ability could prevent a lot of pain and frustration.<\/p>\n<p>This post is aimed at giving you the knowledge that you may (or I should rather say \u201cwill\u201d) need and at persuading you that learning basics of code injection is really worth the little of your time that it takes. I\u2019ll present three different real-world cases where code injection came to my rescue, solving each one with a different tool, fitting best the constraints at hand.<\/p>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">Why You Are Going to Need It<\/span><\/strong><\/p>\n<p>A lot has been already said about the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Aspect-oriented_programming#Motivation_and_basic_concepts\">advantages of AOP<\/a> \u2013 and thus code injection \u2013 so I will only concentrate on a few main points from the troubleshooting point of view.<\/p>\n<p>The coolest thing is that it <strong>enables you to modify third party, closed-source classes<\/strong> and actually even JVM classes. Most of us work with <a href=\"http:\/\/theholyjava.wordpress.com\/2011\/04\/18\/what-do-i-mean-by-a-legacy-code\/\">legacy code<\/a> and code for which we haven\u2019t the source codes and inevitably we occasionally hit the limitations or bugs of these 3rd-party binaries and need very much to change some small thing in there or to gain more insight into the code\u2019s behavior. Without code injection you have no way to modify the code or to add support for increased observability into it. Also you often need to deal with issues or collect information in the production environment where you can\u2019t use a debugger and similar tools while you usually can at least manage somehow your application\u2019s binaries and dependencies. Consider the following situations:<\/p>\n<ul style=\"text-align: left\">\n<li>You\u2019re passing a collection of data to a closed-source library for processing and one method in the library fails for one of the elements but the exception provides no information about which element it was. You\u2019d need to modify it to either log the offending argument or to include it in the exception. (And you can\u2019t use a debugger because it only happens on the production application server.)<\/li>\n<li>You need to collect performance statistics of important methods in your application including some of its closed-source components under the typical production load. (In the production you of course cannot use a profiler and you want to incur the minimal overhead.)<\/li>\n<li>You use JDBC to send a lot of data to a database in batches and one of the batch updates fails. You would need some nice way to find out which batch it was and what data it contained.<\/li>\n<\/ul>\n<p>I\u2019ve in fact encountered these three cases (among others) and you will see possible implementations later.<\/p>\n<p>You should keep the following advantages of code injection in your mind while reading this post:<\/p>\n<ul style=\"text-align: left\">\n<li>Code injection enables you to modify binary classes for which you haven\u2019t the source codes<\/li>\n<li>The injected code can be used to collect various runtime information in environments where you cannot use the traditional development tools such as profilers and debuggers<\/li>\n<li>Don\u2019t Repeat Yourself: When you need the same piece of logic at multiple places, you can define it once and inject it into all those places.<\/li>\n<li>With code injection you do not modify the original source files so it is great for (possibly large-scale) changes that you need only for a limited period of time, especially with tools that make it possible to easily switch the code injection on and off (such as AspectJ with its load-time weaving). A typical case is performance metrics collection and increased logging during troubleshooting<\/li>\n<li>You can inject the code either statically, at the build time, or dynamically, when the target classes are being loaded by the JVM<\/li>\n<\/ul>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">Mini Glossary<\/span><\/strong><\/p>\n<p>You might encounter the following terms in relation to code injection and AOP:<\/p>\n<p>Advice<\/p>\n<blockquote>\n<p>The code to be injected. Typically we talk about before, after, and around advices, which are executed before, after, or instead of a target method. It\u2019s possible to make also other changes than injecting code into methods, e.g. adding fields or interfaces to a class.<\/p>\n<\/blockquote>\n<p>AOP (Aspect Oriented Programming)<\/p>\n<blockquote>\n<p>A programming paradigm claiming that \u201ccross-cutting concerns\u201d \u2013 the logic needed at many places, without a single class where to implement them \u2013 should be implemented once and injected into those places. Check <a href=\"http:\/\/en.wikipedia.org\/wiki\/Aspect-oriented_programming\">Wikipedia<\/a> for a better description.<\/p>\n<\/blockquote>\n<p>Aspect<\/p>\n<blockquote>\n<p>A unit of modularity in AOP, corresponds roughly to a class \u2013 it can contain different advices and pointcuts.<\/p>\n<\/blockquote>\n<p>Joint point<\/p>\n<blockquote>\n<p>A particular point in a program that might be the target of code injection, e.g. a method call or method entry.<\/p>\n<\/blockquote>\n<p>Pointcut<\/p>\n<blockquote>\n<p>Roughly spoken, a pointcut is an expression which tells a code injection tool where to inject a particular piece of code, i.e. to which joint points to apply a particular advice. It could select only a single such point \u2013 e.g. execution of a single method \u2013 or many similar points \u2013 e.g. executions of all methods marked with a custom annotation such as @MyBusinessMethod.<\/p>\n<\/blockquote>\n<p>Weaving<\/p>\n<blockquote>\n<p>The process of injecting code \u2013 advices \u2013 into the target places \u2013 joint points.<\/p>\n<\/blockquote>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\"><br \/>\n<\/span><\/strong><strong><span class=\"Apple-style-span\" style=\"font-size: large\">The Tools<\/span><\/strong><\/p>\n<p>There are many very different tools that can do the job so we will first have a look at the differences between them and then we will get acquainted with three prominent representatives of different evolution branches of code injection tools.<\/p>\n<p><strong>Basic Classification of Code Injection Tools<\/strong><\/p>\n<p><strong>I. Level of Abstraction<\/strong><\/p>\n<p>How difficult is it to express the logic to be injected and to express the pointcuts where the logic should be inserted?<\/p>\n<p>Regarding the \u201cadvice\u201d code:<\/p>\n<ol style=\"text-align: left\">\n<li>Direct bytecode manipulation (e.g. ASM) \u2013 to use these tools you need to understand the bytecode format of a class because they abstract very little from it, you work directly with opcodes, the operand stack and individual instructions. An ASM example:\n<p><i>methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, &#8220;java\/lang\/System&#8221;, &#8220;out&#8221;, &#8220;Ljava\/io\/PrintStream;&#8221;);<\/i><\/p>\n<p>They are difficult to use due to being so low-level but are the most powerful. Usually they are used to implement higher-level tools and only few actually need to use them.<\/li>\n<li>Intermediate level \u2013 code in strings, some abstraction of the classfile structure (Javassist)<\/li>\n<li>Advices in Java (e.g. AspectJ) \u2013 the code to be injected is expressed as syntax-checked and statically compiled Java<\/li>\n<\/ol>\n<p>Regarding the specification of where to inject the code:<\/p>\n<ol style=\"text-align: left\">\n<li>Manual injection \u2013 you have to get somehow hold of the place where you want to inject the code (ASM, Javassist)<\/li>\n<li>Primitive pointcuts \u2013 you have rather limited possibilities for expressing where to inject the code, for example to a particular method, to all public methods of a class or to all public methods of classes in a group (Java EE interceptors)<\/li>\n<li>Pattern matching pointcut expressions \u2013 powerful expressions matching joint points based on a number of criteria with wildcards, awareness of the context (e.g. \u201ccalled from a class in the package XY\u201d) etc. (AspectJ)<\/li>\n<\/ol>\n<p><strong>II. When the Magic Happens<\/strong><\/p>\n<p>The code can be injected at different points in time:<\/p>\n<ul style=\"text-align: left\">\n<li>Manually at run-time \u2013 your code has to explicitly ask for the enhanced code, e.g. by manually instantiating a custom proxy wrapping the target object (this is arguably not true code injection)<\/li>\n<li>At load-time \u2013 the modification are performed when the target classes are being loaded by the JVM<\/li>\n<li>At build-time \u2013 you add an extra step to your build process to modify the compiled classes before packaging and deploying your application<\/li>\n<\/ul>\n<p>Each of these modes of injection can be more suitable at different situations.<\/p>\n<p><strong>III. What It Can Do<\/strong><\/p>\n<p>The code injection tools vary pretty much in what they can or cannot do, some of the possibilities are:<\/p>\n<ul style=\"text-align: left\">\n<li>Add code before\/after\/instead of a method \u2013 only member-level methods or also the static ones?<\/li>\n<li>Add fields to a class<\/li>\n<li>Add a new method<\/li>\n<li>Make a class to implement an interface<\/li>\n<li>Modify an instruction within the body of a method (e.g. a method call)<\/li>\n<li>Modify generics, annotations, access modifiers, change constant values, \u2026<\/li>\n<li>Remove method, field, etc.<\/li>\n<\/ul>\n<p><strong><br \/>\n<\/strong><br \/>\n<strong>Selected Code Injection Tools<\/strong><\/p>\n<p>The best-known code injection tools are:<\/p>\n<ol style=\"text-align: left\">\n<li>Dynamic Java Proxy<\/li>\n<li>The bytecode manipulation library <a href=\"http:\/\/asm.ow2.org\/\">ASM<\/a><\/li>\n<li>JBoss Javassist<\/li>\n<li>AspectJ<\/li>\n<li>Spring AOP\/proxies<\/li>\n<li>Java EE interceptors<\/li>\n<\/ol>\n<p><strong><br \/>\n<\/strong><br \/>\n<strong>Practical Introduction to Java Proxy, Javassist and AspectJ<\/strong><\/p>\n<p>I\u2019ve selected three rather different mature and popular code injection tools and will present them on real-world examples I\u2019ve personally experienced.<\/p>\n<p><strong>The Omnipresent Dynamic Java Proxy<\/strong><\/p>\n<p><a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/api\/java\/lang\/reflect\/Proxy.html\">Java.lang.reflect.Proxy<\/a> makes it possible to create dynamically a proxy for an interface, forwarding all calls to a target object. It is not a code injection tool for you cannot inject it anywhere, you must manually instantiate and use the proxy instead of the original object, and you can do this only for interfaces, but it can still be very useful as we will see.<\/p>\n<p>Advantages:<\/p>\n<ul style=\"text-align: left\">\n<li>It\u2019s a part of JVM and thus is available everywhere<\/li>\n<li>You can use the same proxy \u2013 more exactly an <a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/api\/java\/lang\/reflect\/InvocationHandler.html\">InvocationHandler<\/a> \u2013 for incompatible objects and thus reuse the code more than you could normally<\/li>\n<li>You save effort because you can easily forward all calls to a target object and only modify the ones interesting for you. If you were to implement a proxy manually, you would need to implement all the methods of the interface in question<\/li>\n<\/ul>\n<p>Disadvantages:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<ul style=\"text-align: left\">\n<li>You can create a dynamic proxy only for an interface, you can\u2019t use it if your code expects a concrete class<\/li>\n<li>You have to instantiate and apply it manually, there is no magical auto-injection<\/li>\n<li>It\u2019s little too verbose<\/li>\n<li>Its power is very limited, it can only execute some code before\/after\/around a method<\/li>\n<\/ul>\n<p>There is no code injection step \u2013 you have to apply the proxy manually.<\/p>\n<p><strong>Example<\/strong><\/p>\n<p>I was using JDBC PreparedStatement\u2019s batch updates to modify a lot of data in a database and the processing was failing for one of the batch updates because of integrity constraint violation. The exception didn\u2019t contain enough information to find out which data caused the failure and so I\u2019ve created a dynamic proxy for the PreparedStatement that remembered values passed into each of the batch updates and in the case of a failure it automatically printed the batch number and the data. With this information I was able to fix the data and I kept the solution in place so that if a similar problems ever occurs again, I\u2019ll be able to find its cause and resolve it quickly.<\/p>\n<p>The crucial part of the code:<\/p>\n<p><strong>LoggingStatementDecorator.java \u2013 snippet 1<\/strong><\/p>\n<pre class=\"brush:java\">class LoggingStatementDecorator implements InvocationHandler {\r\n\r\n   private PreparedStatement target;\r\n   ...\r\n\r\n   private LoggingStatementDecorator(PreparedStatement target) { this.target = target; }\r\n\r\n   @Override\r\n   public Object invoke(Object proxy, Method method, Object[] args)\r\n         throws Throwable {\r\n\r\n      try {\r\n         Object result = method.invoke(target, args);\r\n         updateLog(method, args); \/\/ remember data, reset upon successful execution\r\n         return result;\r\n      } catch (InvocationTargetException e) {\r\n         Throwable cause = e.getTargetException();\r\n         tryLogFailure(cause);\r\n         throw cause;\r\n      }\r\n\r\n   }\r\n\r\n   private void tryLogFailure(Throwable cause) {\r\n      if (cause instanceof BatchUpdateException) {\r\n         int failedBatchNr = successfulBatchCounter + 1;\r\n         Logger.getLogger(\"JavaProxy\").warning(\r\n               \"THE INJECTED CODE SAYS: \" +\r\n               \"Batch update failed for batch# \" + failedBatchNr +\r\n               \" (counting from 1) with values: [\" +\r\n               getValuesAsCsv() + \"]. Cause: \" + cause.getMessage());\r\n      }\r\n   }\r\n...\r\n<\/pre>\n<p>Notes:<\/p>\n<p>To create a proxy, you first need to implement an InvocationHandler and its invoke method, which is called whenever any of the interface\u2019s methods is invoked on the proxy<br \/>\nYou can access the information about the call via the java.lang.reflect.* objects and for example delegate the call to the proxied object via method.invoke<br \/>\nWe\u2019ve also an utility method for creating a proxy instance for a Prepared statement:<\/p>\n<p><strong>LoggingStatementDecorator.java \u2013 snippet 2<\/strong><\/p>\n<pre class=\"brush:java\">public static PreparedStatement createProxy(PreparedStatement target) {\r\n  return (PreparedStatement) Proxy.newProxyInstance(\r\n      PreparedStatement.class.getClassLoader(),\r\n      new Class[] { PreparedStatement.class },\r\n      new LoggingStatementDecorator(target));\r\n};\r\n<\/pre>\n<p>Notes:<\/p>\n<ul style=\"text-align: left\">\n<li>You can see that the newProxyInstance call takes a classloader, an array of interfaces that the proxy should implement, and the invocation handler that calls should be delegated to (the handler itself has to manage a reference to the proxied object, if it needs it)<\/li>\n<\/ul>\n<p>It is then used like this:<\/p>\n<p><strong>Main.java<\/strong><\/p>\n<pre class=\"brush:java\">...\r\nPreparedStatement rawPrepStmt = connection.prepareStatement(\"...\");\r\nPreparedStatement loggingPrepStmt = LoggingStatementDecorator.createProxy(rawPrepStmt);\r\n...\r\nloggingPrepStmt.executeBatch();\r\n...\r\n<\/pre>\n<p>Notes:<\/p>\n<ul style=\"text-align: left\">\n<li>You see that we have to manually wrap a raw object with the proxy and use the proxy further on<\/li>\n<\/ul>\n<p><strong><i><br \/>\n<\/i><\/strong><br \/>\n<strong><i>Alternative Solutions<\/i><\/strong><\/p>\n<p>This problem could be solved in different ways, for example by creating a non-dynamic proxy implementing PreparedStatement and forwarding all calls to the real statement while remembering batch data but it would be lot of boring typing for the interface has many methods. The caller could also manually keep track of the data it has send to the prepared statement but that would obscure its logic with an unrelated concern.<\/p>\n<p>Using the dynamic Java proxy we get rather clean and easy to implement solution.<\/p>\n<p><strong>The Independent Javassist<\/strong><\/p>\n<p><a href=\"http:\/\/www.javassist.org\/\">JBoss Javassist<\/a> is an intermediate code injection tool providing a higher-level abstraction than bytecode manipulation libraries and offering little limited but still very useful manipulation capabilities. The code to be injected is represented as strings and you have to manually get to the class-method where to inject it. Its main advantage is that the modified code has no new run-time dependencies, on Javassist or anything else. This may be the decisive factor if you are working for a large corporation where the deployment of additional open-source libraries (or just about any additional libraries) such as AspectJ is difficult for legal and other reasons.<\/p>\n<p>Advantages:<\/p>\n<ul style=\"text-align: left\">\n<li>Code modified by Javassist doesn\u2019t require any new run-time dependencies, the injection happens at the build time and the injected advice code itself doesn\u2019t depend on any Javassist API<\/li>\n<li>Higher-level than bytecode manipulation libraries, the injected code is written in Java syntax, though enclosed in strings<\/li>\n<li>Can do most things that you may need such as \u201cadvising\u201d method calls and method executions<\/li>\n<li>You can achieve both build-time injection (via Java code or a <a href=\"http:\/\/theholyjava.wordpress.com\/2010\/06\/25\/implementing-build-time-instrumentation-with-javassist\/\">custom Ant task to do execution\/call advising<\/a>) and load-time injection (by implementing your own <a href=\"http:\/\/download.oracle.com\/javase\/1.5.0\/docs\/api\/java\/lang\/instrument\/package-summary.html\">Java 5+ agent<\/a> [thx to Anton])<\/li>\n<\/ul>\n<p>Disadvantages:<\/p>\n<ul style=\"text-align: left\">\n<li>Still little too low-level and thus harder to use \u2013 you have to deal a little with structure of methods and the injected code is not syntax-checked<\/li>\n<li>Javassist has no tools to perform the injection and you thus have to implement your own injection code \u2013 including that there isn\u2019t support for injecting the code automatically based on a pattern<\/li>\n<\/ul>\n<p>(See GluonJ below for a solution without most of the disadvantages of Javassist.)<\/p>\n<p>With Javassist you create a class, which uses the Javassist API to inject code int targets and run it as a part of your build process after the compilation, for example as I once did via a custom Ant task.<\/p>\n<p><strong>Example<\/strong><\/p>\n<p>We needed to add some simple performance monitoring to our Java EE application and we were not allowed to deploy any non-approved open-source library (at least not without going through a time-consuming approval process). We\u2019ve therefore used Javassist to inject the performance monitoring code to our important methods and to the places were important external methods were called.<\/p>\n<p>The code injector:<\/p>\n<p><strong>JavassistInstrumenter.java<\/strong><\/p>\n<pre class=\"brush:java\">public class JavassistInstrumenter {\r\n\r\n   public void insertTimingIntoMethod(String targetClass, String targetMethod) throws NotFoundException, CannotCompileException, IOException {\r\n      Logger logger = Logger.getLogger(\"Javassist\");\r\n      final String targetFolder = \".\/target\/javassist\";\r\n\r\n      try {\r\n         final ClassPool pool = ClassPool.getDefault();\r\n         \/\/ Tell Javassist where to look for classes - into our ClassLoader\r\n         pool.appendClassPath(new LoaderClassPath(getClass().getClassLoader()));\r\n         final CtClass compiledClass = pool.get(targetClass);\r\n         final CtMethod method = compiledClass.getDeclaredMethod(targetMethod);\r\n\r\n         \/\/ Add something to the beginning of the method:\r\n         method.addLocalVariable(\"startMs\", CtClass.longType);\r\n         method.insertBefore(\"startMs = System.currentTimeMillis();\");\r\n         \/\/ And also to its very end:\r\n         method.insertAfter(\"{final long endMs = System.currentTimeMillis();\" +\r\n            \"iterate.jz2011.codeinjection.javassist.PerformanceMonitor.logPerformance(\\\"\" +\r\n            targetMethod + \"\\\",(endMs-startMs));}\");\r\n\r\n         compiledClass.writeFile(targetFolder);\r\n         \/\/ Enjoy the new $targetFolder\/iterate\/jz2011\/codeinjection\/javassist\/TargetClass.class\r\n\r\n         logger.info(targetClass + \".\" + targetMethod +\r\n               \" has been modified and saved under \" + targetFolder);\r\n      } catch (NotFoundException e) {\r\n         logger.warning(\"Failed to find the target class to modify, \" +\r\n               targetClass + \", verify that it ClassPool has been configured to look \" +\r\n               \"into the right location\");\r\n      }\r\n   }\r\n\r\n   public static void main(String[] args) throws Exception {\r\n      final String defaultTargetClass = \"iterate.jz2011.codeinjection.javassist.TargetClass\";\r\n      final String defaultTargetMethod = \"myMethod\";\r\n      final boolean targetProvided = args.length == 2;\r\n\r\n      new JavassistInstrumenter().insertTimingIntoMethod(\r\n            targetProvided? args[0] : defaultTargetClass\r\n            , targetProvided? args[1] : defaultTargetMethod\r\n      );\r\n   }\r\n}\r\n<\/pre>\n<p>Notes:<\/p>\n<ul style=\"text-align: left\">\n<li>You can see the \u201clow-levelness\u201d \u2013 you have to explicitly deal with objects like CtClass, CtMethod, explicitly add a local variable etc.<\/li>\n<li>Javassist is rather flexible in where it can look for the classes to modify \u2013 it can search the classpath, a particular folder, a JAR file, or a folder with JAR files<\/li>\n<li>You would compile this class and run its main during your build process<\/li>\n<\/ul>\n<p><strong>Javassist on Steroids: GluonJ<\/strong><\/p>\n<p><a href=\"http:\/\/www.csg.is.titech.ac.jp\/projects\/gluonj\/documentation\/tutorial.html\">GluonJ<\/a> is an AOP tool building on top of Javassist. It can use either a custom syntax or Java 5 annotations and it\u2019s build around the concept of \u201crevisers\u201d. Reviser is a class \u2013 an aspect \u2013 that revises, i.e. modifies, a particular target class and overrides one or more of its methods (contrary to inheritance, the reviser\u2019s code is physically imposed over the original code inside the target class).<\/p>\n<p>Advantages:<\/p>\n<ul style=\"text-align: left\">\n<li>No run-time dependencies if build-time weaving used (load-time weaving requires the GluonJ agent library or gluonj.jar)<\/li>\n<li>Simple Java syntax using GlutonJ\u2019s annotation \u2013 though the custom syntax is also trivial to understand and easy to use<\/li>\n<li>Easy, automatic weaving into the target classes with GlutonJ\u2019s JAR tool, an Ant task or dynamically at the load-time<\/li>\n<li>Support for both build-time and load-time weaving<\/li>\n<\/ul>\n<p>Disadvantages:<\/p>\n<ul style=\"text-align: left\">\n<li>An aspect can modify only a single class, you cannot inject the same piece of code to multiple classes\/methods<\/li>\n<li>Limited power \u2013 only provides for field\/method addition and execution of a code instead of\/around a target method, either upon any of its executions or only if the execution happens in a particular context, i.e. when called from a particular class\/method<\/li>\n<\/ul>\n<p>If you don\u2019t need to inject the same piece of code into multiple methods then GluonJ is easier and better choice than Javassist and if its simplicity isn\u2019t a problem for you then it also might be a better choice than AspectJ just thanks to this simplicity.<\/p>\n<p><strong>The Almighty AspectJ<\/strong><\/p>\n<p>AspectJ is a full-blown AOP tool, it can do nearly anything you might want, including the modification of static methods, addition of new fields, addition of an interface to a class\u2019 list of implemented interfaces etc.<\/p>\n<p>The syntax of AspectJ advices comes in two flavours, one is a superset of Java syntax with additional keywords like aspect and pointcut, the other one \u2013 called @AspectJ \u2013 is standard Java 5 with annotations such as @Aspect, @Pointcut, @Around. The latter is perhaps easier to learn and use but also little less powerful as it isn\u2019t as expressive as the custom AspectJ syntax.<\/p>\n<p>With AspectJ you can define which joint points to advise with very powerful expressions but it may be little difficult to learn them and to get them right. There is a useful Eclipse plugin for AspectJ development \u2013 the <a href=\"http:\/\/www.eclipse.org\/ajdt\/\">AspectJ Development Tools<\/a> (AJDT) \u2013 but the last time I\u2019ve tried it it wasn\u2019t as helpful as I\u2019d have liked.<\/p>\n<p>Advantages:<\/p>\n<ul style=\"text-align: left\">\n<li>Very powerful, can do nearly anything you might need<\/li>\n<li>Powerful pointcut expressions for defining where to inject an advice and when to activate it (including some run-time checks) \u2013 fully enables DRY, i.e. write once &amp; inject many times<\/li>\n<li>Both build-time and load-time code injection (weaving)<\/li>\n<\/ul>\n<p>Disadvantages:<\/p>\n<ul style=\"text-align: left\">\n<li>The modified code depends on the AspectJ runtime library<\/li>\n<li>The pointcut expressions are very powerful but it might be difficult to get them right and there isn\u2019t much support for \u201cdebugging\u201d them though the AJDT plugin is partially able to visualize their effects<\/li>\n<li>It will likely take some time to get started though the basic usage is pretty simple (using @Aspect, @Around, and a simple pointcut expression, as we will see in the example)<\/li>\n<\/ul>\n<p><strong><br \/>\n<\/strong><br \/>\n<strong>Example<\/strong><\/p>\n<p>Once upon time I was writing a plugin for a closed-source LMS J2EE application having such dependencies that it wasn\u2019t feasible to run it locally. During an API call, a method deep inside the application was failing but the exception didn\u2019t contain enough information to track the cause of the problem. I therefore needed to change the method to log the value of its argument when it fails.<\/p>\n<p>The AspectJ code is quite simple:<\/p>\n<p><strong>LoggingAspect.java<\/strong><\/p>\n<pre class=\"brush:java\">@Aspect\r\npublic class LoggingAspect {\r\n\r\n   @Around(\"execution(private void TooQuiet3rdPartyClass.failingMethod(..))\")\r\n   public Object interceptAndLog(ProceedingJoinPoint invocation) throws Throwable {\r\n      try {\r\n         return invocation.proceed();\r\n      } catch (Exception e) {\r\n         Logger.getLogger(\"AspectJ\").warning(\r\n            \"THE INJECTED CODE SAYS: the method \" +\r\n            invocation.getSignature().getName() + \" failed for the input '\" +\r\n            invocation.getArgs()[0] + \"'. Original exception: \" + e);\r\n         throw e;\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<p>Notes:<\/p>\n<ul style=\"text-align: left\">\n<li>The aspect is a normal Java class with the @Aspect annotation, which is just a marker for AspectJ<\/li>\n<li>The @Around annotation instructs AspectJ to execute the method instead of the one matched by the expression, i.e. instead of the failingMethod of the TooQuiet3rdPartyClass<\/li>\n<li>The around advice method needs to be public, return an Object, and take a special AspectJ object carrying information about the invocation \u2013 ProceedingJoinPoint \u2013 as its argument and it may have an arbitrary name (Actually this is the minimal form of the signature, it could be more complex.)<\/li>\n<li>We use the <a href=\"http:\/\/www.eclipse.org\/aspectj\/doc\/released\/runtime-api\/org\/aspectj\/lang\/ProceedingJoinPoint.html\">ProceedingJoinPoint<\/a> to delegate the call to the original target (an instance of the TooQuiet3rdPartyClass) and, in the case of an exception, to get the argument\u2019s value<\/li>\n<li>I\u2019ve used an @Around advice though @AfterThrowing would be simpler and more appropriate but this shows better the capabilities of AspectJ and can be nicely compared to the dynamic java proxy example above<\/li>\n<\/ul>\n<p>Since I hadn\u2019t control over the application\u2019s environment, I couldn\u2019t enable the load-time weaving and thus had to use <a href=\"http:\/\/www.eclipse.org\/aspectj\/doc\/released\/devguide\/antTasks-iajc.html\">AspectJ\u2019s Ant task<\/a> to weave the code at the build time, re-package the affected JAR and re-deploy it to the server.<\/p>\n<p><strong><i>Alternative Solutions<\/i><\/strong><\/p>\n<p>Well, if you can\u2019t use a debugger then your options are quite limited. The only alternative solution I could think of is to <a href=\"http:\/\/java.decompiler.free.fr\/\">decompile<\/a> the class (illegal!), add the logging into the method (provided that the decompilation succeeds), re-compile it and replace the original .class with the modified one.<\/p>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">The Dark Side<\/span><\/strong><\/p>\n<p>Code injection and Aspect Oriented Programming are very powerful and sometimes indispensable both for troubleshooting and as a regular part of application architecture, as we can see e.g. in the case of Java EE\u2019s Enterprise Java Beans where the business concerns such as transaction  management and security checks are injected into POJOs (though implementations actually more likely use proxies) or in Spring.<\/p>\n<p>However there is a price to be paid in terms of possibly decreased understandability as the runtime behavior and structure are different from what you\u2019d expect based on the source codes (unless you know to check also the aspects\u2019 sources or unless the injection is made explicit by annotations on the target classes such as Java EE\u2019s <a href=\"http:\/\/download.oracle.com\/javaee\/6\/api\/javax\/interceptor\/Interceptors.html\">@Interceptors<\/a>). Therefore you must carefully weight the benefits and drawbacks of code injection\/AOP \u2013 though when used reasonably, they do not obscure the program flow more than interfaces, factories etc. The <a href=\"http:\/\/www.ibm.com\/developerworks\/java\/library\/j-aopwork15\/index.html#N10223\">argument about obscuring code is perhaps often over-estimated<\/a>.<\/p>\n<p>If you want to see an example of AOP gone wild, check the <a href=\"http:\/\/sourceforge.net\/projects\/glassbox\/files\/glassbox\/2.0\/glassbox-src.zip\/download\">source codes<\/a> of <a href=\"http:\/\/glassbox.sourceforge.net\/\">Glassbox<\/a>, a JavaEE performance monitoring tool (for that you might need a <a href=\"http:\/\/theholyjava.wordpress.com\/2008\/10\/31\/webapp-performance-monitoring-with\/\">map<\/a> not to get too lost).<\/p>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">Fancy Uses of Code Injection and AOP<\/span><\/strong><\/p>\n<p>The main field of application of code injection in the process of troubleshooting is logging, more exactly gaining visibility into what an application is doing by extracting and somehow communicating interesting runtime information about it. However AOP has many interesting uses beyond \u2013 simple or complex \u2013 logging, for example:<\/p>\n<ul style=\"text-align: left\">\n<li>Typical examples: Caching &amp; et al (ex.: <a href=\"http:\/\/www.theserverside.com\/news\/thread.tss?thread_id=39026#200714\">on AOP in JBoss Cache<\/a>), transaction management, logging, enforcement of security, persistence, thread safety, error recovery, automatic implementation of methods (e.g. toString, equals, hashCode), remoting<\/li>\n<li>Implementation of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Role-oriented_programming\">role-based programming<\/a> (e.g. <a href=\"http:\/\/www.eclipse.org\/objectteams\/\">OT\/J<\/a>, using BCEL) or the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Data,_Context,_and_Interaction\">Data, Context, and Interaction<\/a> architecture<\/li>\n<li>Testing<\/li>\n<ul>\n<li>Test coverage \u2013 inject code to record whether a line has been executed during test run or not<\/li>\n<li><a href=\"http:\/\/www.cs.gmu.edu\/~offutt\/rsrch\/papers\/mujava.pdf\">Mutation testing<\/a> (<a href=\"http:\/\/www.cs.gmu.edu\/~offutt\/mujava\/\">\u00b5Java<\/a>, <a href=\"http:\/\/jumble.sourceforge.net\/\">Jumble<\/a>) \u2013 inject \u201crandom\u201d mutation to the application and verify that the tests failed<\/li>\n<li><a href=\"http:\/\/www.patterntesting.com\/\">Pattern Testing<\/a> \u2013 automatic verification that Architecture\/Design\/Best practices recommendations are implemented correctly in the code via AOP<\/li>\n<li>Simulate hardware\/external failures by <a href=\"http:\/\/www.eclipse.org\/aspectj\/sample-code.html#testing-inoculated-injectIOException\">injecting the throwing of an exception<\/a><\/li>\n<\/ul>\n<li>Help to achieve zero turnaround for Java applications \u2013 <a href=\"http:\/\/www.zeroturnaround.com\/forum\/topic.php?id=1265&amp;replies=3#post-5207\">JRebel uses an AOP-like approach<\/a> for framework and server integration plugins \u2013 namely its <a href=\"http:\/\/www.zeroturnaround.com\/jrebel\/features\/\">plugins<\/a> <a href=\"http:\/\/www.zeroturnaround.com\/resources\/jrebel-plugins\/\">use Javassist<\/a> for \u201cbinary patching\u201d<\/li>\n<li>Solving though problems and avoiding monkey-coding with AOP patterns such as Worker Object Creation (turn direct calls into asynchronous with a Runnable and a ThreadPool\/task queue) and Wormhole (make context information from a caller available to the callee without having to pass them through all the layers as parameters and without a ThreadLocal) \u2013 described in the book AspectJ in Action<\/li>\n<li>Dealing with legacy code \u2013 overriding the class instantiated on a call to a constructor (this and similar may be used to break tight-coupling with feasible amount of work), <a href=\"http:\/\/www.sonatype.com\/people\/2007\/11\/two-fantastic-uses-for-aspectj-part-one-backward-compatibility\/\">ensuring backwards-compatibility<\/a>  o , <a href=\"http:\/\/www.sonatype.com\/people\/2007\/12\/two-fantastic-uses-for-aspectj-part-two-bridging\/\">teaching components to react properly<\/a> on environment changes<\/li>\n<li>Preserving backwards-compatibility of an API while not blocking its ability to evolve e.g. by adding backwards-compatible methods when return types have been narrowed\/widened (<a href=\"http:\/\/bridge-method-injector.infradna.com\/\">Bridge Method Injector<\/a> \u2013 uses ASM) or by <a href=\"http:\/\/www.sonatype.com\/people\/2007\/11\/two-fantastic-uses-for-aspectj-part-one-backward-compatibility\/\">re-adding old methods<\/a> and implementing them in terms of the new API<\/li>\n<li>Turning POJOs into JMX beans<\/li>\n<\/ul>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\"><br \/>\n<\/span><\/strong><br \/>\n<strong><span class=\"Apple-style-span\" style=\"font-size: large\">Summary<\/span><\/strong><\/p>\n<p>We\u2019ve learned that code injection can be indispensable for troubleshooting, especially when dealing with closed-source libraries and complex deployment environments. We\u2019ve seen three rather different code injection tools \u2013 dynamic Java proxies, Javassist, AspectJ \u2013 applied to real-world problems and discussed their advantages and disadvantages because different tools may be suitable for different cases. We\u2019ve also mentioned that code injection\/AOP shouldn\u2019t be overused and looked at some examples of advanced applications of code injection\/AOP.<\/p>\n<p>I hope that you now understand how code injection can help you and know how to use these three tools.<\/p>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">Source Codes<\/span><\/strong><\/p>\n<p>You can <a href=\"https:\/\/github.com\/jakubholynet\/JavaZone-Code-Injection\">get the fully-documented source codes of the examples<\/a> from GitHub including not only the code to be injected but also the target code and support for easy building. The easiest may be:<\/p>\n<pre class=\"brush:bash\">git clone git:\/\/github.com\/jakubholynet\/JavaZone-Code-Injection.git\r\ncd JavaZone-Code-Injection\/\r\ncat README\r\nmvn -P javaproxy test\r\nmvn -P javassist test\r\nmvn -P aspectj   test\r\n<\/pre>\n<p>(It may take few minutes for Maven do download its dependencies, plugins, and the actual project\u2019s dependencies.)<\/p>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">Additional Resources<\/span><\/strong><\/p>\n<ul style=\"text-align: left\">\n<li><a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.0.x\/reference\/aop.html\">Spring\u2019s introduction into AOP<\/a><\/li>\n<li>dW: <a href=\"http:\/\/www.ibm.com\/developerworks\/java\/library\/j-aopwork15\/index.html\">AOP@Work: AOP myths and realities<\/a><\/li>\n<li><a href=\"http:\/\/www.manning.com\/laddad2\/Samplechapter1.pdf\">Chapter 1 of AspectJ in Action<\/a>, 2nd. ed.<\/li>\n<\/ul>\n<p><strong><span class=\"Apple-style-span\" style=\"font-size: large\">Acknowledgements<\/span><\/strong><\/p>\n<p>I would like to thank all the people who helped me with this post and the presentation including my colleges, the JRebel folk, and GluonJ\u2019s co-author prof. Shigeru Chiba.<\/p>\n<p><strong><i>Reference:<\/i><\/strong> <a href=\"http:\/\/theholyjava.wordpress.com\/2011\/09\/07\/practical-introduction-into-code-injection-with-aspectj-javassist-and-java-proxy\/\">Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Jakub Hol\u00fd at <a href=\"http:\/\/theholyjava.wordpress.com\/\">The Holy Java blog<\/a>.<\/p>\n<p><strong>Related Articles:<\/strong><\/p>\n<ul style=\"text-align: left\">\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/02\/domain-driven-design-spring-aspectj.html\">Domain Driven Design with Spring and AspectJ<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/07\/aspect-oriented-programming-with-spring.html\">Aspect Oriented Programming with Spring AspectJ and Maven<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/01\/aspect-oriented-programming-spring-aop.html\">Aspect Oriented Programming with Spring AOP<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/01\/10-tips-proper-application-logging.html\">10 Tips for Proper Application Logging<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially to troubleshooting problems in third-party libraries without source codes or in an environment where it isn\u2019t possible to use a debugger or a profiler. Code injection is also useful for &hellip;<\/p>\n","protected":false},"author":16,"featured_media":88,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[252,74,73,251,253,250],"class_list":["post-544","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-aop","tag-aspect-oriented-programming","tag-aspectj","tag-code-injection","tag-java-proxy","tag-jboss-javassist"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2011-09-21T08:32:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T20:13:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/aspectj-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jakub Holy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/HolyJak\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jakub Holy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html\"},\"author\":{\"name\":\"Jakub Holy\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/7b7d87e493b5f8388635d4315b062727\"},\"headline\":\"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy\",\"datePublished\":\"2011-09-21T08:32:00+00:00\",\"dateModified\":\"2012-10-21T20:13:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html\"},\"wordCount\":4170,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/aspectj-logo.jpg\",\"keywords\":[\"AOP\",\"Aspect Oriented Programming\",\"AspectJ\",\"Code Injection\",\"Java Proxy\",\"JBoss Javassist\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html\",\"name\":\"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/aspectj-logo.jpg\",\"datePublished\":\"2011-09-21T08:32:00+00:00\",\"dateModified\":\"2012-10-21T20:13:18+00:00\",\"description\":\"The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/aspectj-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/aspectj-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/09\\\/practical-introduction-into-code.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/7b7d87e493b5f8388635d4315b062727\",\"name\":\"Jakub Holy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7ee9569bd027b442ce03e2cc44cbc8791448ab502e0e2c70cbc6186f64d6e1f5?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7ee9569bd027b442ce03e2cc44cbc8791448ab502e0e2c70cbc6186f64d6e1f5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7ee9569bd027b442ce03e2cc44cbc8791448ab502e0e2c70cbc6186f64d6e1f5?s=96&d=mm&r=g\",\"caption\":\"Jakub Holy\"},\"description\":\"Jakub is an experienced Java[EE] developer working for a lean &amp; agile consultancy in Norway. He is interested in code quality, developer productivity, testing, and in how to make projects succeed.\",\"sameAs\":[\"http:\\\/\\\/theholyjava.wordpress.com\",\"http:\\\/\\\/www.linkedin.com\\\/in\\\/jakubholydotnet\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/HolyJak\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Jakub-Holy\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy - Java Code Geeks","description":"The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html","og_locale":"en_US","og_type":"article","og_title":"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy - Java Code Geeks","og_description":"The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially","og_url":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2011-09-21T08:32:00+00:00","article_modified_time":"2012-10-21T20:13:18+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/aspectj-logo.jpg","type":"image\/jpeg"}],"author":"Jakub Holy","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/HolyJak","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Jakub Holy","Est. reading time":"22 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html"},"author":{"name":"Jakub Holy","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/7b7d87e493b5f8388635d4315b062727"},"headline":"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy","datePublished":"2011-09-21T08:32:00+00:00","dateModified":"2012-10-21T20:13:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html"},"wordCount":4170,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/aspectj-logo.jpg","keywords":["AOP","Aspect Oriented Programming","AspectJ","Code Injection","Java Proxy","JBoss Javassist"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html","url":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html","name":"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/aspectj-logo.jpg","datePublished":"2011-09-21T08:32:00+00:00","dateModified":"2012-10-21T20:13:18+00:00","description":"The ability to inject pieces of code into compiled classes and methods, either statically or at runtime, may be of immense help. This applies especially","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/aspectj-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/aspectj-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2011\/09\/practical-introduction-into-code.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/7b7d87e493b5f8388635d4315b062727","name":"Jakub Holy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/7ee9569bd027b442ce03e2cc44cbc8791448ab502e0e2c70cbc6186f64d6e1f5?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/7ee9569bd027b442ce03e2cc44cbc8791448ab502e0e2c70cbc6186f64d6e1f5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7ee9569bd027b442ce03e2cc44cbc8791448ab502e0e2c70cbc6186f64d6e1f5?s=96&d=mm&r=g","caption":"Jakub Holy"},"description":"Jakub is an experienced Java[EE] developer working for a lean &amp; agile consultancy in Norway. He is interested in code quality, developer productivity, testing, and in how to make projects succeed.","sameAs":["http:\/\/theholyjava.wordpress.com","http:\/\/www.linkedin.com\/in\/jakubholydotnet","https:\/\/x.com\/http:\/\/twitter.com\/HolyJak"],"url":"https:\/\/www.javacodegeeks.com\/author\/Jakub-Holy"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/544","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=544"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/544\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/88"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=544"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=544"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=544"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}