186 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES Listing 10-2. @SuppressWarnings Annotation Usage class DeprecatedUsage { @SuppressWarnings(”deprecation”) public void useDeprecatedMethod() { Dep.myDeprecatedMethod(); } } After adding the annotation, the compiler won t complain anymore. The @Override Annotation The third JDK 5.0 annotation is @Override. Use of this annotation tells the compiler that the method is supposed to be overriding a method in the superclass. The compiler will warn you if it doesn t. This will catch common mistakes, such as a method with the wrong case for example, hashcode() versus hashCode(). In such a case, a quick scan through the code may look right, and the compiler won t complain at compilation time. Only after your resultant program produces odd results when hashCode() should be called does the problem of the incorrect case in your method reveal itself. Well, it doesn t exactly reveal itself, but you know something is wrong, and you have to hunt down the problem. By using the annotation, errors of this nature will be caught much sooner in the development process. Listing 10-3 shows a program with a poorly overridden method. Listing 10-3. @Override Annotation Usage public class Over { public void overrideMe() { } } class SubOver extends Over { @Override public void overrideme() { } } Notice the poorly capitalized method without camelcase for the m in me. Had the source code not included the @Override annotation, the compiler would not have complained, producing a SubOver class with an overrideme() method. Any call to the overrideMe() method of SubOver would then result in the version in the parent class being called instead.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
184 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES That is the whole annotation declaration; it is like a class definition. It is for the predefined annotation Deprecated, to be described shortly. JDK 5.0 Annotations JDK 5.0 introduces three annotations: @Deprecated, @SuppressWarnings, and @Override. Let s take a quick look at what was available to us before Java SE 6.0. The @Deprecated Annotation One of the JDK 5.0 annotations is @Deprecated. Notice the difference in case. It is different from the javadoc @deprecated tag, as it doesn t go in javadoc comments. Instead, you place @Deprecated above the method or class you want to flag as out of date. The positioning of both tags is shown in Listing 10-1. Listing 10-1. @Deprecated Annotation Usage public class Dep { /** * @deprecated Don’t use this method any more. */ @Deprecated public static void myDeprecatedMethod() { System.out.println(”Why did you do that?”); } } class DeprecatedUsage { public void useDeprecatedMethod() { Dep.myDeprecatedMethod(); } } There is a second class in Listing 10-1 that uses the deprecated method: DeprecatedUsage. When you compile the source code with the javac compiler, you get a warning: > javac Dep.java Note: Dep.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES 185 Then, compiling with the specified -Xlint option shows the details: > javac -Xlint:deprecation Dep.java Dep.java:11: warning: [deprecation] myDeprecatedMethod() in Dep has been deprecated Dep.myDeprecatedMethod(); ^ 1 warning Nothing new here. This is the JDK 5.0 @Deprecate annotation just another way of doing what @deprecated does. The @SuppressWarnings Annotation There are two types of annotations: those that accept arguments and those that don t. The @Deprecated annotation is an example of one that doesn t. The @SuppressWarnings annotation is one that does. With the @Deprecated annotation, a method or class is either deprecated or it isn t. Adding the metadata is an on/off flag. On the other hand, the @SuppressWarnings annotation says you would like to either suppress a specific type of warning or not. The types will be specific to the compiler vendor. For Sun s compiler, there are two warnings that can be suppressed: deprecation and unchecked. An unchecked value has to do with compile-time checks for generics. If you don t want to update legacy code to avoid warnings related to generics, you can add an @SuppressWarnings annotation to your source: @SuppressWarnings({”unchecked”}) Note You can add the suppression at the class or method level. If at the class level, all warnings of unchecked usages in the class will be suppressed. The argument to the annotation is an array of strings hence the extra set of {}s in there. If instead of suppressing warnings related to generics you want to avoid the warning generated by compiling the source in Listing 10-1, you would add an @SuppressWarnings({”deprecation”}) annotation to where the deprecated method call was made. Listing 10-2 shows an updated DeprecatedUsage class.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
Pluggable Annotation Processing Updates CHAPTER 10 Are you apt to use the apt tool? Annotations are a concept introduced with the 5.0 release of J2SE and JSR 175. In this chapter, you ll explore those annotations added to Java SE 6. Although this is a Java 6 book, since annotations are so new, it is best to start with a description of what exactly they are and how to use them, and not just focus on the new ones. Confused yet? First, apt stands for the annotation processing tool. It is a new command-line tool that comes with the JDK. (Well, it was new for the 5.0 release.) You use annotations to annotate your source code, and apt to make new annotations. Annotations are @ tags that appear in source, not javadoc-style comments. They have corresponding classes in the system, either as part of the core libraries or created by you. For instance, the @deprecated javadoc tag can be thought of as an annotation, although it isn t exactly. It acts as metadata that affects how tools and libraries interact with your classes. The @deprecated tag tells the compiler to generate a compilation warning when you use the method or class. Before digging too deeply into annotations, though, it is important to repeat a line from the Java documentation: Typical application programmers will never have to define an annotation type (see http://java.sun.com/j2se/1.5.0/docs/guide/language/ annotations.html). However, defining annotations is different than using them. So, let s look at using a few first. Before going into the specifics of what to do with annotations, here s what an annotation declaration looks like: package java.lang; import java.lang.annotation.*; @Documented @Retention(RetentionPolicy.RUNTIME) public @interface Deprecated { } 183
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
182 CHAPTER 9 SCRIPTING AND JSR 223 Assuming you start with a matching language, you are then in interactive mode with the script runner. > jrunscript js> Just enter your JavaScript interactively and it will be evaluated. You can also have the tool evaluate whole files by using the -f option from the command line. Get Your Pnuts Here JavaScript isn t the only scripting engine available, just the only one that ships with Mustang. Pronounced like peanuts, Pnuts is another engine that works with JSR 223. It s available from https://pnuts.dev.java.net. You can find configuration information at http://pnuts.org/snapshot/latest/extensions/jsr223/doc/index.html. Hopefully, by the time Mustang ships, other scripting languages, such as Ruby or PHP, will be available in a JSR 223 installable configuration. Note JSR 274 is about the BeanShell scripting language. It s not part of Mustang, but supposedly works alongside JSR 223. The Groovy programming language is JSR 241. It s not part of Mustang, either. Summary From what appears to be a long way from where JSR 223 started, Mustang gets a common scripting framework for integrating scripting engines with the Java platform. From evaluating the scripting source, to compiling and invoking, your Java programs can be bilingual with full object transparency between the two languages. In fact, you can even implement interfaces on the fly in the scripting language if you want to, without even generating .class files. As you get started with scripting, be sure to test your scripts in the command-line support tool. The book s final chapter looks at the last big additions to Mustang improvements in the pluggable annotation processing area. First introduced with Java 1.5, the metadata facility allows the marking of attributes for classes, interfaces, fields, and methods. In Chapter 10, you ll discover the additional features available for the processing of your types and elements.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
CHAPTER 9 SCRIPTING AND JSR 223 181 System.err.println(e); } catch (ScriptException e) { System.err.println(e); } } } Running the program just displays the string sent to the JavaScript print() method. > java InterfaceTest wave jrunscript Mustang includes some new programs in the bin directory of the JDK. Many of these are considered experimental, at least in the beta release. One such program is jrunscript. Think of it as command-line access to the installed scripting engines. You can try out anything with jrunscript that you would pass into the eval() method of a ScriptEngine. First, to see what engines are installed, you can pass a -q option to jrunscript: jrunscript -q Language ECMAScript 1.6 implemention “Mozilla Rhino” 1.6 release 2 Tip To see all the available commands from jrunscript, use the -? or -help command-line options. With only one available in the default installation from Sun, you don t have to explicitly request to use a specific engine. But, if multiple were available, you could explicitly request a language with the -l option. The language string to pass in would be one of those returned from the scripting engine factory s getNames() method. As Listing 9-1 showed, any of the following will work for the provided ECMAScript 1.6 engine: js, rhino, JavaScript, javascript, ECMAScript, or ecmascript. Yes, the names are case sensitive. > jrunscript -l javascripT script engine for language javascripT can not be found
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
180 CHAPTER 9 SCRIPTING AND JSR 223 By itself, this doesn t make Invocable that great of an operation but it has a second side: its getInterface() method. With the getInterface() method, you can dynamically create new implementations of interfaces by defining the implementations of an interface s methods in the scripting language. Let s take this one a little more slowly by looking at a specific interface. The Runnable interface has one method: run(). If your scripting language has made a run() method invocable, you can acquire an instance of the Runnable interface from the Invocable engine. First, evaluate a no-argument run() method to make it invocable: engine.eval(”function run() {print(’wave’);}”); Next, associate it to an instance of the interface: Runnable runner = invokeEngine.getInterface(Runnable.class); You can now pass this Runnable object to a Thread constructor for execution: Thread t = new Thread(runner); t.start(); Listing 9-6 puts all these pieces together. There is an added Thread.join() call to ensure that the newly created thread finishes before the program exits. Listing 9-6. Using Invocable to Implement Interfaces import javax.script.*; public class InterfaceTest { public static void main(String args[]) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName(”javascript”); try { engine.eval(”function run() {print(’wave’);}”); Invocable invokeEngine = (Invocable)engine; Runnable runner = invokeEngine.getInterface(Runnable.class); Thread t = new Thread(runner); t.start(); t.join(); } catch (InterruptedException e) {
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
178 CHAPTER 9 SCRIPTING AND JSR 223 The CompileTest example here just adds 1 to a counter variable stored in the bindings of the ScriptEngine. Since the script is evaluated three times, its final value is 3. > java CompileTest Counter: 1.0 Counter: 2.0 Counter: 3.0 Compiling scripts can also be done from files, or more specifically, from Reader strings. Compilation is most beneficial for both large code blocks and those that execute repeatedly. The Invocable Interface Invocable is another optional interface that a scripting engine can implement. An invocable engine supports the calling of functions scripted in that engine s language. Not only can you call functions directly, but you can also bind functions of the scripting language to interfaces in Java space. Once a method/function has been evaluated by the engine, it can be invoked via the invoke() method of Invocable assuming of course that the engine implements the interface. Invocable functions can also be passed parameters that don t have to come through bindings; just pass in the method name to be executed and its arguments. To demonstrate, Listing 9-5 takes the earlier string reversal example from Listing 9-3 and makes the reversal code an invocable function. Listing 9-5. Using Invocable to Reverse Strings import javax.script.*; import java.io.*; public class InvocableTest { public static void main(String args[]) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName(”javascript”); if (args.length == 0) { System.err.println(”Please pass name(s) on command line”); System.exit(-1); }
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 9 SCRIPTING AND JSR 223 179 try { engine.eval( “function reverse(name) {” + ” var output = ‘’;” + ” for (i = 0; i <= name.length; i++) {" + " output = name.charAt(i) + output" + " }" + " return output;" + "}"); Invocable invokeEngine = (Invocable)engine; Console console = System.console(); for (Object name: args) { Object o = invokeEngine.invoke("reverse", name); console.printf("%s / %s%n", name, o); } } catch (NoSuchMethodException e) { System.err.println(e); } catch (ScriptException e) { System.err.println(e); } } } Running this program involves passing multiple strings via the command-line arguments. Each one passed along the command line will be displayed in both a forward and backward fashion. > java InvocableTest one two three one / eno two / owt three / eerht Caution There are two invoke() methods of Invocable. Sometimes the arguments can be ambiguous, and the compiler can t determine which of the two methods to use, as they both accept a variable number of arguments. In Listing 9-5, the enhanced for loop said each element was an Object, even though we knew it to be a String. This was to appease the compiler without adding a casting operation.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
176 CHAPTER 9 SCRIPTING AND JSR 223 public class FlipBindings { public static void main(String args[]) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName(”javascript”); if (args.length != 1) { System.err.println(”Please pass name on command line”); System.exit(-1); } try { engine.put(”name”, args[0]); engine.eval( “var output = ‘’;” + “for (i = 0; i <= name.length; i++) {" + " output = name.charAt(i) + output" + "}"); String name = (String)engine.get("output"); Console console = System.console(); console.printf("Reversed: %s%n", name); } catch (ScriptException e) { System.err.println(e); } } } Passing in the book name to the program shows the reversed title: > java FlipBindings “Java 6 Platform Revealed” Reversed: delaeveR mroftalP 6 avaJ Note Errors in the JavaScript source are handled by the caught ScriptException. It is best to at least print out this exception, as it will reveal errors in the script code. You can also get the file name, line number, and column number in which the error happened.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services