|
5/24 |
2006/2/21-23 [Computer/SW/Languages/Java] UID:41939 Activity:nil |
2/21 What is the best way to get the current method name in Java? So far I have seen 3 approaches: 1. Create new Exception, grab the first frame off its stack trace. Inelegant, requires creating a stack trace (expensive). \_ Yeah it sucks. Yeah it does much more work than you need. Yeah it is really fragile and may break when you switch java implementations because some moron changed how stack traces are printed. Still, the few times I've seen libraries that generate method names this is how they did it. 2. Generate new stack trace, grab the first frame. Same problems as above but slightly better. 3. For each method, define a static final String containing its name. Very fast, but makes the code 'brittle' in terms of refactoring and makes classes needlessly cluttered. Anyone know a better way? \_ A little more information about what you are trying to do would be helpful. The obvious answer is you wrote the method, you should know what name you gave it, but I assume this is not tenable in your context. Have you looked at com.sun.jdi? \_ Trying to provide debug-level printouts of what the current function is, as in: public void fooFunc() { System.out.println("Entered fooFunc()"); ... } \_ I think AspectJ is the solution for you, then. See: http://csua.org/u/f19 - pp \_ That is neat. I don't suppose there's any good system for debugging AspectJ code? That's the main thing that is keeping me away. \_ AspectJ generates vanilla java bytecodes. Any debugger should be able to debug it. http://csua.org/u/f1a I think Eclipse might have some dev support. - pp \_ Just because a debugger can debug it doesn't mean it is debugable. Just try say, breaking at a line number and having ANY chance at being right. \_ My my, the motd is buzzword compliant today. \_ Why? The use of 'solution' to describe a solution? \_ AspectJ is buzzword-ware. It's amazing how many inelegant solutions like AspectJ exist to get around Java's stupid limitations. \_ Well what language has good support for 'crosscutting concerns'? \_ CLOS. The CLOS Meta-Object Protocol is where many of the AspectJ ideas come from. \_ Lisp?! Nooooooo! \_ I recommend "Beyond Java" for a good overview of why Java is a pain in the ass, and why "frameworks" and "design patterns" are often inelegent attempts to get around inherent defects in the language. \_ Gee, the man behind on of the most inelegent java frameworks ever wants to tell me how to write an elegant language? |
5/24 |
|
csua.org/u/f19 -> www.eclipse.org/aspectj/doc/released/progguide/starting-development.html#tracing Next Development Aspects The next two sections present the use of aspects in increasingly sophisticated ways. Development aspects are easily removed from production builds. Production aspects are intended to be used in both development and in production, but tend to affect only a few classes. This section presents examples of aspects that can be used during development of Java applications. These aspects facilitate debugging, testing and performance tuning work. The aspects define behavior that ranges from simple tracing, to profiling, to testing of internal consistency within the application. Using AspectJ makes it possible to cleanly modularize this kind of functionality, thereby making it possible to easily enable and disable the functionality when desired. Tracing This first example shows how to increase the visibility of the internal workings of a program. It is a simple tracing aspect that prints a message at specified method calls. In our figure editor example, one such aspect might simply trace whenever points are drawn. Within all advice bodies this variable is bound to an object that describes the current join point. draw(GraphicsContext)) To understand the benefit of coding this with AspectJ consider changing the set of method calls that are traced. With AspectJ, this just requires editing the definition of the tracedCalls pointcut and recompiling. The individual methods that are traced do not need to be edited. When debugging, programmers often invest considerable effort in figuring out a good set of trace points to use when looking for a particular kind of problem. When debugging is complete or appears to be complete it is frustrating to have to lose that investment by deleting trace statements from the code. The alternative of just commenting them out makes the code look bad, and can cause trace statements for one kind of debugging to get confused with trace statements for another kind of debugging. With AspectJ it is easy to both preserve the work of designing a good set of trace points and disable the tracing when it isn t being used. This is done by writing an aspect specifically for that tracing mode, and removing that aspect from the compilation when it is not needed. This ability to concisely implement and reuse debugging configurations that have proven useful in the past is a direct result of AspectJ modularizing a crosscutting design element the set of methods that are appropriate to trace when looking for a given kind of information. Profiling and Logging Our second example shows you how to do some very specific profiling. Although many sophisticated profiling tools are available, and these can gather a variety of information and display the results in useful ways, you may sometimes want to profile or log some very specific behavior. In these cases, it is often possible to write a simple aspect similar to the ones above to do the job. For example, the following aspect counts the number of calls to the rotate method on a Line and the number of calls to the set* methods of a Point that happen within the control flow of those calls to rotate: aspect SetsInRotateCounting { int rotateCount = 0; and How many times are methods defined on Point objects whose name begins with "set" called in fulfilling those rotate calls? questions it may be difficult to express using standard profiling or logging tools. Pre- and Post-Conditions Many programmers use the "Design by Contract" style popularized by Bertand Meyer in Object-Oriented Software Construction, 2/e. In this style of programming, explicit pre-conditions test that callers of a method call it properly and explicit post-conditions test that methods properly do the work they are supposed to. AspectJ makes it possible to implement pre- and post-condition testing in modular form. Notice that the setX pointcut refers to all the operations that can set a Point's x coordinate; this includes the setX method, as well as half of the setXY method. In this sense the setX pointcut can be seen as involving very fine-grained crosscutting -- it names the the setX method and half of the setXY method. Even though pre- and post-condition testing aspects can often be used only during testing, in some cases developers may wish to include them in the production build as well. Again, because AspectJ makes it possible to modularize these crosscutting concerns cleanly, it gives developers good control over this decision. Contract Enforcement The property-based crosscutting mechanisms can be very useful in defining more sophisticated contract enforcement. One very powerful use of these mechanisms is to identify method calls that, in a correct program, should not exist. For example, the following aspect enforces the constraint that only the well-known factory methods can add an element to the registry of figure elements. Enforcing this constraint ensures that no figure element is added to the registry more than once. canRegister() { throw new IllegalAccessException("Illegal call " + thisJoinPoint); This is a property-based pointcut because it identifies join points based not on their signature, but rather on the property that they occur specifically within the code of another method. The before advice declaration effectively says signal an error for any calls to register that are not within the factory methods. This advice throws a runtime exception at certain join points, but AspectJ can do better. Using the declare error form, we can have the compiler signal the error. canRegister(): "Illegal call" } When using this aspect, it is impossible for the compiler to compile programs with these illegal calls. In this case, since we depend only on static information (the withincode pointcut picks out join points totally based on their code, and the call pointcut here picks out join points statically). Other enforcement, such as the precondition enforcement, above, does require dynamic information such as the runtime value of parameters. Configuration Management Configuration management for aspects can be handled using a variety of make-file like techniques. To work with optional aspects, the programmer can simply define their make files to either include the aspect in the call to the AspectJ compiler or not, as desired. Developers who want to be certain that no aspects are included in the production build can do so by configuring their make files so that they use a traditional Java compiler for production builds. To make it easy to write such make files, the AspectJ compiler has a command-line interface that is consistent with ordinary Java compilers. |
csua.org/u/f1a -> www.eclipse.org/aspectj/sample-code.html#trails-debugging-aspectj11 AspectJ sample code This contains contributions from the AspectJ community of * sample code for AspectJ programs, * sample code for extensions to AspectJ tools using the public API's, * sample scripts for invoking AspectJ tools, and * documentation trails showing how to do given tasks using AspectJ, AJDT, or various IDE or deployment environments. java:28 | protected interface SoughtException {} // XXX ajc broken here? This picks out the mistake * of declaring SoughtException a parent of something * that is not an exception at all. staticinitialization(Throwable+) : "all SoughtException must be subclasses of Throwable"; org/technology/ajdt/dev/update, install the plug-in, and follow any post-install instructions. You can also recompile by clicking the AJDT build button. For servlets and JSP's, that is in {Web Root}/WEB-INF/lib. Servlet runners and J2EE web containers should run AspectJ programs fine if the classes and required libraries are deployed as usual. jar should be deployed where it will be loaded by a common classloader. html:44 | Tomcat 4x uses the Jasper engine based on Ant to compile JSP's. jar in ${CATALINA_HOME}/common/lib so that it can be loaded by Jasper. jar should be in {webapp}/WEB-INF/lib or some shared or common directory supported by the server. xml, at which point the web application can be reloaded. jar is already deployed in any of places on the Tomcat application classpath (the application, shared, or common classpath). java:36 | /* * To work with an object right when it is constructed, * understand the differences between the join points for * constructor call, constructor execution, and initialization. Before executing the String constructor, * this uses the target object, which is not constructed. java:18 | /** private default implementation of library */ class PrivatePointcutLibrary { pointcut adviceCflow() : cflow(adviceexecution; static aspect A { declare parents: PointcutLibrary extends VendorPointcutLibrary; public pointcut anyRunnableImplementation() : staticinitialization(Runnable+); io classes * (but not methods declared only on their subclasses). swing methods or constructors * (but not methods declared only on their subclasses). html:28 | AspectJ in Action by Ramnivas Laddad has sample code including four patterns: the worker object creation pattern, the exception introduction pattern, the participant pattern, and the wormhole pattern. html:45 | In the OOPSLA 2002 paper Design Pattern Implementation in Java and AspectJ Jan Hannemann and Gregor Kiczales discuss the implementation in AspectJ of 23 of the traditional "gang of four" design patterns (from the book Design Patterns: elements of reusable object-oriented software by Gamma, Helm, Johnson, and Vlissides). aTrack project aims to create an open source bug tracking application that demonstrates use of Aspect-Oriented Programming (AOP) with AspectJ. It uses AOP pragmatically to provide systematic support for technical, middleware, and business concerns. Since the advice might throw the injected fault, it must declare that it throws IOException. When advice declares exceptions thrown, the compiler will emit an error if any join point is not also declared to throw an IOException. In this case, the testCheckPoint pointcut only picks out methods that throw IOException, so the compile will not signal any errors. java:28 | /** * After returning a PrinterStream from any call in our * packages, verify it by doing a round-trip between * PrinterStream and BufferedPrinterStream. make(BufferedPrinterStream)) { BufferedPrinterStream bufferStream = new BufferedPrinterStream(stream); equals(newStream)) { throw new Error("round-trip failed for " + stream); the advice code in the target class can have source attributes that point back to the aspect file. At the time of this writing, Sun's VM supports it, but not some others, which means that the Sun VM must be used as the runtime VM. Because the VM does all the work of associating the source line with the code being debugged, debuggers should be able to operate normally with AspectJ 10 source files even if they weren't written with that in mind, if they use the correct API's to the debugger. Unfortunately, some debuggers take shortcuts based on the default case of one file per class in order to avoid having the VM calculate the file suffix or package prefix. html:43 | The AspectJ 11 compiler usually implements advice as call-backs to the aspect, which means that most AspectJ programs do not require JSR-45 support in order to be debugged. However, it does do a limited amount of advice inlining; Because inlined advice can be more efficient, we plan to support JSR-45 as soon as feasible. This will require upgrading the BCEL library we use to pass around the correct source attributes. Sometimes debuggers correctly get the source line information, but fail when they attempt to parse AspectJ source files expected to contain Java code. |