Enterprise Java Technologies Tech Tips Tips, Techniques, and Sample Code Welcome to the Enterprise Java Technologies Tech Tips for September 30, 2005. Here you'll get tips on using enterprise Java technologies and APIs, such as those in Java 2 Platform, Enterprise Edition (J2EE) and Java Platform, Enterprise Edition (Java EE). This issue covers: * Accessing the Bean Environment in EJB 3.0 Session Beans * Tech Tips Quiz The EJB 3.0 tip is based on an open source reference implementation of Java EE 5 called GlassFish. You can download GlassFish from the GlassFish Project page (https://glassfish.dev.java.net/). You can also download the sample package for the EJB 3.0 tip at http://java.sun.com/developer/EJTechTips/download/resources.zip. Any use of this code and/or information below is subject to the license terms at http://developers.sun.com/dispatcher.jsp?uid=6910008. The quiz is based on the J2EE, v 1.4 SDK. You can download the SDK at http://java.sun.com/j2ee/1.4/download.html. You can view this issue of the Tech Tips on the Web at http://java.sun.com/developer/EJTechTips/2005/tt0930.html. See the Subscribe/Unsubscribe note at the end of this newsletter to subscribe to Tech Tips that focus on technologies and products in other Java platforms. Any use of the code and/or information below is subject to the license terms at http://developers.sun.com/dispatcher.jsp?uid=6910008. For more Java technology content, visit these sites: java.sun.com - The latest Java platform releases, tutorials, and newsletters. java.net - A web forum for collaborating and building solutions together. java.com - Hot games, cool apps -- Experience the power of Java technology. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACCESSING THE BEAN ENVIRONMENT IN EJB 3.0 SESSION BEANS by Deepa Singh The Enterprise JavaBeans 3.0 Specification - JSR 220 (http://jcp.org/aboutJava/communityprocess/pr/jsr220/index.html) gives developers a lot of flexibility in where to specify resource dependencies and how those resources can be deployed on the Java EE 5 platform. This Tech Tip describes how Enterprise JavaBeans 3.0 (EJB 3.0) session beans declare dependencies on external resources, and how dependencies can be injected into EJB 3.0 session beans. The tip also describes how EJB3.0 session beans can refer to the home or business interfaces of enterprise beans using logical names called EJB references. The examples in this tip are based on an open source reference implementation of Java EE 5 called GlassFish. You can download GlassFish from the GlassFish Project page (https://glassfish.dev.java.net/). Note: It's possible to describe the EJB environment (such as resource references and EJB references) in either an ejb-jar.xml file or a bean class. In general, the EJB environment should be described in an ejb-jar.xml file only when it can't be described through annotation in the bean class (for example, because of some business logic). This tip does not discuss the overlap between elements in an ejb-jar.xml file and annotations in the bean class. All bean-specific information in this tip is in vendor-specific deployment descriptors (in sun-ejb-jar.xml). Resource Dependency Injection Mechanisms You can annotate a field or method in an EJB3.0 session bean to request injection of a resource. You do this by annotating a bean's instance variables or setter methods as targets for dependency injection. The container injects these references before any business methods are invoked on the bean instance. Each injection of an object corresponds to a JNDI lookup. Let's look at some examples of injection. Field Level Injection Here's an example of an EJB3.0 session bean that is annotated with resource dependencies: package com.sun.test.ejb30; import javax.ejb.*; import javax.annotation.*; public class StatefulBean implements RemoteStatefulInterface{ @Resource javax.sql.DataSource ejb30DB; @Resource javax.mail.Session ejbmailSession; } The @Resource annotation declares the dependencies, and in this example specifies no additional parameters. However, a @Resource annotation can optionally have two parameters: "name" and "type". When the resource type can be determined from the variable type, the @Resource annotation does not have to specify the type of object accessed. In the previous example, it's clear from the variable ejb30DB type that the variable refers to a javax.sql.DataSource resource, and so the "type" parameter of @Resource is not specified. The second parameter of the @Resource annotation is the "name" parameter. It refers to the logical name of the resource in the component's environment (java:comp/env). The Java EE 5 specification states: By default, the name of the field is combined with the fully-qualified name of the class and used directly as the name in the application component's naming context. In the previous example, the field named ejb30DB in the class StatefulBean in the package pe.ejb.ejb30.session.resources.bean would correspond to the JNDI name java:comp/env/pe.ejb.ejb30.session.resources.bean/ejb30DB. (Most developers won't need to know the default JNDI name unless their application requires them to override the default JNDI name through deployment descriptors.) If the default JNDI name is not used, then the "name" parameter can be used to explicitly specify the JNDI name. Note that the JNDI name is always relative to the java:comp/env naming context. For example, here's a @Resource annotation that specifies both a "name" and "type" parameter: @Resource(name="jdbc/sqetestDB",type=javax.sql.DataSource.class) public javax.sql.DataSource myTestDB; Although the type of the resource is specified in the example, it isn't necessary -- it can be determined implicitly from the variable type. Setter Injection Setter injection gives you an alternative to the container's initialization of variables. In setter injection, you inject resources into a class through methods. The method follows naming conventions for JavaBeans properties. The annotation is applied to the set method for the property -- this is the method that is called to inject the resource reference into the class. Here's an example of setter injection: @Resource // reference name is inferred from the property name private void setMyDB(DataSource ds){ myDB=ds; } private DataSource myDB; The JavaBeans property name (not the method name) is used for corresponding the default JNDI name. If the resource type can be determined from the setter method parameter type, the annotation does not need to specify the type of the object to be accessed. If the name of the resource is the same as the property name corresponding to the setter method, its resource name doesn't need to be explicitly specified. Here, the variable myDB, which corresponds to the setter method for the variable setMyDB (according to JavaBeans property setter naming conventions), corresponds to the JNDI name java:comp/env/com.sun.test.ejb30.StatefulBean/myDB. Here's another example: @Resource(name="jdbc/customerDB") public void setDataSource(DataSource myDB) { this.ds = myDB; } private DataSource myDB; Here, the JNDI name of the resource myDB is jdbc/customerDB. EJB References In addition to injecting resource dependencies, you can also inject bean references in a field or setter property method (only field level injection will be covered here because developers are expected to use this technique most often). Use the @EJB annotation to inject either a session bean's or entity bean's interfaces, which can be either local or remote. You can use the @EJB annotation to look up both EJB 3.0 and EJB 2.1 bean references. Here's an example of an @EJB annotation that demonstrates the injection of a bean interface: @EJB LocalStatelessInterface sless; In this example, sless is a business interface of another bean It has the default JNDI name java:comp/env/sless (in accordance with the Java EE 5 specification), and is packaged in the same ejb-jar file as the referencing bean. If the default JNDI name is not used, the @EJB annotation can be specified with a "name" parameter that refers to the logical name of the referenced bean (just like ), and is independent of how the reference is mapped to a physical bean. For example: @EJB(name="ejb/stateless") LocalStatelessInterface sless; In the case of a reference to an EJB 2.x bean, the reference would be to the bean's Home interface. For example: @EJB(name="ejb/stateless") RemoteStatelessHome slessHome; Explicit Dependency Lookup Through the EJBContext API A new method, "lookup", has been added to the javax.ejb.EJBContext interface. This method can be used to lookup the resources or references bound in a bean's JNDI environment naming context. The method's signature is: Object lookup(String name) The lookup method internally wraps a call to InitialContext.lookup() so that a developer doesn't need to additionally learn the JNDI API. The SessionContext is injected by the EJB Container immediately after the bean is created, and the SessionContext object is then used to lookup resources. Here's a comparison of explicitly looking up a bean reference in EJB 2.1 and explicitly looking up a bean reference in EJB 3.0 (without annotation): EJB 2.1: Initial Context ic=new InitialContext(); Object o=ic.lookup("ejb/FirstStateless"); //perform Portable Narrowing of the object to the //corresponding home interface of the bean statelessHome= (StatelessRemoteHome)PortableRemoteObject.narrow(objref, StatelessRemoteHome.class); EJB 3.0: @Resource SessionContect sc public void setup(){ FirstStatelessInterface fi=(FirstStatelessInterface)sc.lookup("ejb/FirstStateless"); } Dependency Injection in an Application Client Note that you can also perform resource injection in an application client's main class. Application clients have the same lifecycle as J2SE applications. Because of this, the entry point for a container to an application client is through the client's static main method. This means that dependency injections in an application client container must be static, that is, the fields or methods for injection must be static. For example: private static @EJB RemoteStatefulInterface sful; Developers have a choice as to what design pattern (instance or field level injection) to use for resources or bean references, irrespective of whether the access is from a bean or application client. For more information about accessing the bean environment in EJB 3.0 session beans, see the EJB 3.0 specification (http://jcp.org/aboutJava/communityprocess/pr/jsr220/index.html). Also see the Java EE 5 specification (http://www.jcp.org/en/jsr/detail?id=244). Running the Sample A sample package accompanies this tip. The code in the sample package includes some (but not all) of the code examples in the tip, and demonstrates some of the techniques covered in the tip. To install and run the sample: 1. Install GlassFish (unless its already installed). You can download GlassFish from the GlassFish Project-Download Binary Builds page (https://glassfish.dev.java.net/public/downloadsindex.html). Select a build that's appropriate for your environment and download it. Then follow the instructions on the Download page to complete the installation. 2. Set the following environment variables: - S1AS_HOME. This should point to where you installed GlassFish (for example C:\Sun\AppServer) - ANT_HOME. This should point to where ant is installed. Ant is included in the GlassFish bundle that you downloaded. (In Windows, it's in the lib\ant subdirectory.) - JAVA_HOME. This should point to the location of JDK 5.0 on your system. Also, add the ant location to your PATH environment variable. 3. Download the sample package (http://java.sun.com/developer/EJTechTips/download/resources.zip). Then change to the directory where you downloaded the package and unzip the package. The result is a directory called resources that contains the source files and other support files for the sample. 4. Change to the resource directory and edit the config.properties files as appropriate. For example, if the admin host is remote change admin.host from the default value (localhost) to the appropriate remote host. 5. Start GlassFish by entering the following command: asadmin start-domain --user admin --password administrator domain1 6. Run following commands: ant build This will compile classes and create an EAR file. Class files and EAR files are generated inside the resources/ejb30 directory. ant setup This will deploy necessary resources onto GlassFish. ant deploy This will deploy the created EAR file. ant run This will run an application client and invoke the deployed EAR file. You should see the following in response: runclient-common: [echo] Executing appclient at C:\ws\appserver-sqe\pe\ejb\ejb30\session\stateful\resources [exec] Invoking 3.0 SFSB--------> [exec] Message from 3.0 SFSB: hello [exec] invoking stateless... [exec] Message from 3.0 Stateless Bean: Hello from Stateless bean [exec] SFSB Invoked Stateless Bean successfully [exec] Message from 3.0 Stateless Bean to SFSB: Hello from Stateless bean: SFSB Invoked Sless [exec] Removed SFSB by calling remove business method: [exec] Test Complete--------------> 7. After running the sample, you can undeploy it and delete any resources created in GlassFish through the following commands: ant undeploy This undeploys the application. ant unsetup This deletes all the resources created in GlassFish. About the Author Deepa Singh is the lead test developer for the EJB container in the Sun Java Enterprise Application Server group. She has been involved with the EJB specification since J2EE version 1.2.1, and is quite excited about EJB3.0 and Java EE 5. Deepa has been a member of the Sun Java Enterprise Application Server group since February 2001. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TECH TIPS QUIZ Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics. Here's a short quiz that tests your knowledge of some topics covered in past Tech Tips. You can find the answers at the end of the quiz. 1) Which of the following is a "pull" parser? a) Xerces b) SSAX c) Sun Java Streaming XML Parser (SJSXP) d) None of the above 2) Which of the following WSDL binding style/use combinations are WS-I compliant? a) RPC/encoded b) RPC/literal c) Document/encoded d) Document/literal e) None of the above 3) Which of the following is a valid binding expression in JavaServer Faces (JSF) technology? a) #{invoice.customerName} b) ${invoice.date} c) #[customer.status == 'VIP'] d) None of the above. 4) What do the following elements in a web.xml deployment descriptor specify: ja Shift_JIS zh_TW Big5 a) Use the Shift_JIS charset for any servlet response whose locale is set to ja, and the Big5 charset for any servlet response whose locale is set to zh_TW Traditional Chinese. b) Include the Shift_JIS charset in the list of character sets that the container can choose from for servlet responses whose locale is set to ja, and include the Big5 charset in the list of character sets that the container can choose from for servlet responses whose locale is set to zh_TW Traditional Chinese. c) Nothing -- there is no element. 5) Which of the following statements are true about message-driven beans: a) A message-driven bean's instances retain no data or conversational state for a specific client. b) All instances of a message-driven bean are equivalent, allowing the EJB container to assign a message to any message-driven bean instance. c) A single message-driven bean can process messages from multiple clients. d) All of the above. e) None of the above. Answers 1) Which of the following is a "pull" parser? c) Sun Java Streaming XML Parser (SJSXP). SJSXP is a high-speed implementation of the Streaming API for XML parser (StAX). SJSXP is a pull parser (by comparison, Xerces and SSAX are SAX parsers). SJSXP implements a pull method, where the parser maintains a pointer of sorts to the currently-scanned location in the document--this is often called a cursor. You simply ask the parser for the node that the cursor currently points to by using either of two APIs that SJSXP provides: cursor and iterator. The cursor API returns the XML information as strings, while the iterator API returns discrete event objects in the order in which they are read by the parser. For more information about SJSXP, see the February 22, 2005 Tech Tip "Introducing the Sun Java Streaming XML Parser (http://java.sun.com/developer/EJTechTips/2005/tt0222.html#2). 2) Which of the following WSDL binding style/use combinations are WS-I compliant? a) RPC/encoded b) RPC/literal c) Document/encoded d) Document/literal e) None of the above b and d. RPC/literal and Document/literal are WS-I compliant. You can learn more about the binding style/use combinations in the June 22, 2005 Tech Tip "JAX-RPC Binding Styles and Use Attributes" (http://java.sun.com/developer/EJTechTips/2005/tt0622.html#1). 3) Which of the following is a valid binding expression in JavaServer Faces (JSF) technology? a) #{invoice.customerName} The syntax of binding expressions is based on the JavaServer Pages (JSP) 2.0 Expression Language, which itself is based on the object accessing syntax of JavaScript. In JSP, expressions are delimited with "${}", but in JSF they are delimited with "#{}". Learn more in the September 23, 2004 Tech Tip "Value and Method Binding Expressions in JavaServer Faces Technology" (http://java.sun.com/developer/EJTechTips/2004/tt0923.html#1). Note that updates have been made in JSF 1.2 to unify its expression language with JSP 2.1. For more about the new, unified expression language, see the technical article "Unified Expression Language" (http://java.sun.com/products/jsp/reference/techart/unifiedEL.html). 4) What do the following elements in a web.xml deployment descriptor specify: ja Shift_JIS zh_TW Big5 a) Use the Shift_JIS charset for any servlet response whose locale is set to ja, and the Big5 charset for any servlet response whose locale is set to zh_TW Traditional Chinese. The Java Servlet 2.4 API introduced a new element in the web.xml deployment descriptor. This allows you to assign locale-to-charset mappings. For more information, see the April 25, 2005 Tech Tip "Improved Internationalization in the Java Servlet 2.4 API" (http://java.sun.com/developer/EJTechTips/2005/tt0425.html#2). 5) Which of the following statements are true about message-driven beans: d) All of the above. For more information about MDBs, see March 22, 2005 Tech Tip "Using Message-Driven Beans with EJB 2.1" (http://java.sun.com/developer/EJTechTips/2005/tt0322.html#1). . . . . . . . . . . . . . . . . . . . . . . . Please read our Terms of Use and Licensing policies: http://www.sun.com/share/text/termsofuse.html http://developers.sun.com/dispatcher.jsp?uid=6910008 PRIVACY STATEMENT: Sun respects your online time and privacy (http://sun.com/privacy). You have received this based on your e-mail preferences. If you would prefer not to receive this information, please follow the steps at the bottom of this message to unsubscribe. * FEEDBACK Comments? Send your feedback on the Enterprise Java Technologies Tech Tips to: http://developers.sun.com/contact/feedback.jsp?category=sdn * SUBSCRIBE/UNSUBSCRIBE Subscribe to other Java developer Tech Tips: - Core Java Technologies Tech Tips. Get tips on using core Java technologies and APIs, such as those in the Java 2 Platform, Standard Edition (J2SE). - Wireless Developer Tech Tips. Get tips on using wireless Java technologies and APIs, such as those in the Java 2 Platform, Micro Edition (J2ME). To subscribe to these and other JDC publications: - Go to the Sun Developer Network - Subscriptions page, (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), choose the newsletters you want to subscribe to and click "Submit". - To unsubscribe, go to the Subscriptions page, (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), uncheck the appropriate checkbox, and click "Submit". - To use our one-click unsubscribe facility, see the link at the end of this email: - ARCHIVES You'll find the Enterprise Java Technologies Tech Tips archives at: http://java.sun.com/developer/EJTechTips/index.html - COPYRIGHT Copyright 2005 Sun Microsystems, Inc. All rights reserved. 901 San Antonio Road, Palo Alto, California 94303 USA. This document is protected by copyright. For more information, see: http://java.sun.com/developer/copyright.html Enterprise Java Technologies Tech Tips September 30, 2005 Trademark Information: http://www.sun.com/suntrademarks/ Java, J2SE, J2EE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.