Copyright © 2006 ObjectWeb Consortium
This work is licensed under the Creative Commons Attribution-ShareAlike License. To view a copy of this license,visit http://creativecommons.org/licenses/by-sa/2.0/deed.en or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
$Id: developerguide.xml 216 2006-03-16 19:01:07Z benoitf $
Abstract
The EasyBeans developer guide is intended for developers wanting to work with the source distribution of EasyBeans. People wanted to contribute to EasyBeans should read this documentation.
Table of Contents
Table of Contents
A JDK 5.0 is required to build EasyBeans. Make sure that the JDK used to build EasyBeans is compliant with the new 5.0 features.
The ant tool is used with build.xml
files to
build EasyBeans. This tool is available at http://ant.apache.org.
The test suite of EasyBeans uses the TestNG tool. This tool is available at http://www.testng.org.
The test suite of EasyBeans uses Clover, which is a code-coverage, analysis tool. Cenqua has granted licenses to open source projects. Refer to http://www.cenqua.com/ for more about Clover.
The EasyBeans project provides .project and .classpath for Eclipse 3.1 or greater. A project is ready to use once the source has been imported using the Eclipse tool. Eclipse tool is available at http://www.eclipse.org.
The eclipse-checkstyle plugin is used to check the javadoc of Easybeans project. A warning will print if the EasyBeans coding convention is not used. This plugin is available at http://eclipse-cs.sourceforge.net.
As part of the EasyBeans coding convention, the use of tabulation characters is disallowed. Files should contain only spaces. The AnyEdit plugin allows tabs to be converted to spaces when saving the file. Also, trailing spaces can be removed automatically.
This plugin is available at http://andrei.gmxhome.de/anyedit/.
EasyBeans uses bytecode enhancement. This is done using the ObjectWeb ASM project. ASM provides a plugin that allows the ASM code of a given class to be obtained. The plugin is available at http://asm.objectweb.org/eclipse/index.html.
The EasyBeans test suite uses TestNG. A plugin is available for Eclipse: http://testng.org/doc/eclipse.html.
To compile EasyBeans, launch the command ant compile in the root directory of the project (named easybeans by default) being launched.
![]() | Note |
---|---|
The command ant -p can be used to list the targets that are available. |
Once the command has been run successfully, an output
folder is created with a subfolder
classes
. This classes
folder contains the generated
classes.
ant clean is used to clean the generated classes.
Javadoc of EasyBeans can be generated by using ant javadoc
The resulting documentation will be available in the output/dist/javadoc
folder.
Binary jar files are built using ant jar.
The generated jar files are located in the output/dist
folder.
rar files are generated (one for JOnAS application server) using ant rar.
The rar file is located in the output/dist
folder.
Anyone can check out source code from the SVN server using the following command (for GUI SVN client use, configuration values are the same as for command line use):
svn checkout svn://svn.forge.objectweb.org/svnroot/easybeans easybeans
Table of Contents
The build.xml
file located in the project root
will be used to launch the EasyBeans server. This file is contained in the
source distribution.
Use the following command: ant run.server
The EasyBeans server will be launched and the following output will be printed:
Buildfile: /home/benoitf/workspace/easybeans/build.xml init: [mkdir] Created dir: /home/benoitf/workspace/easybeans/output [mkdir] Created dir: /home/benoitf/workspace/easybeans/output/manifest [mkdir] Created dir: /home/benoitf/workspace/easybeans/output/dist [mkdir] Created dir: /home/benoitf/workspace/easybeans/output/classes [mkdir] Created dir: /home/benoitf/workspace/easybeans/output/dist/javadoc compile: [javac] Compiling 246 source files to /home/benoitf/workspace/easybeans/output/classes [copy] Copying 9 files to /home/benoitf/workspace/easybeans/output/classes run.server: [java] Mar 14, 2006 4:53:47 PM org.objectweb.easybeans.log.CommonsLoggerImpl warn [java] WARNING: No directory was configured, take the default value of /home/benoitf/workspace/easybeans/ejb3s. [java] Mar 14, 2006 4:53:47 PM org.objectweb.easybeans.log.CommonsLoggerImpl warn [java] WARNING: Directory /home/benoitf/workspace/easybeans/ejb3s created. [java] Mar 14, 2006 4:53:47 PM org.objectweb.carol.util.configuration.TraceCarol infoCarol [java] INFO: Name service for jrmp is started on port 1099 [java] Mar 14, 2006 4:53:47 PM org.objectweb.easybeans.log.CommonsLoggerImpl info [java] INFO: List of all MBeans descriptors [java] Mar 14, 2006 4:53:47 PM org.objectweb.easybeans.log.CommonsLoggerImpl info [java] INFO: Found managedBean EJB3Deployer. [java] Mar 14, 2006 4:53:47 PM org.objectweb.easybeans.log.CommonsLoggerImpl info [java] INFO: End of list of all MBeans descriptors [java] Mar 14, 2006 4:53:48 PM org.objectweb.jotm.Current <init> [java] INFO: JOTM 2.0.11 [java] Mar 14, 2006 4:53:48 PM org.objectweb.easybeans.log.CommonsLoggerImpl info [java] INFO: Startup was done in '684' ms. [java] Mar 14, 2006 4:53:48 PM org.objectweb.easybeans.log.CommonsLoggerImpl info [java] INFO: '0' containers have been created. [java] Mar 14, 2006 4:53:48 PM org.objectweb.easybeans.log.CommonsLoggerImpl info [java] INFO: Waiting requests...
EasyBeans is now launched and it is ready to handle EJBs.
Table of Contents
Before running the examples, be sure to follow the requirements for compiling and running these EasyBeans examples.
The ant tool is used to build the
examples. To compile the examples, use the
build.xml
file that is located in the examples
directory.
The command ant
install_all_examples
must be launched in the examples
directory:
$ ant install_all_examples Buildfile: build.xml install_all_examples: init: compile: [javac] Compiling 7 source files to /home/benoitf/workspace/easybeans/output/example-classes install.persistence: install.war: [mkdir] Created dir: /home/benoitf/workspace/easybeans/webapps/stateless.war/WEB-INF/classes [copy] Copying 6 files to /home/benoitf/workspace/easybeans/webapps/stateless.war/WEB-INF/classes [copy] Copying 1 file to /home/benoitf/workspace/easybeans/webapps/stateless.war/WEB-INF install: [copy] Copying 5 files to /home/benoitf/workspace/easybeans/ejb3s/stateless.jar [jar] Building jar: /home/benoitf/workspace/easybeans/clients/client-stateless.jar init: compile: [javac] Compiling 3 source files to /home/benoitf/workspace/easybeans/output/example-classes install.persistence: install.war: install: [copy] Copying 2 files to /home/benoitf/workspace/easybeans/ejb3s/stateful.jar [jar] Building jar: /home/benoitf/workspace/easybeans/clients/client-stateful.jar init: compile: [javac] Compiling 4 source files to /home/benoitf/workspace/easybeans/output/example-classes install.persistence: [mkdir] Created dir: /home/benoitf/workspace/easybeans/ejb3s/entitybean.jar/META-INF [copy] Copying 1 file to /home/benoitf/workspace/easybeans/ejb3s/entitybean.jar/META-INF install.war: install: [copy] Copying 4 files to /home/benoitf/workspace/easybeans/ejb3s/entitybean.jar [jar] Building jar: /home/benoitf/workspace/easybeans/clients/client-entitybean.jar init: compile: [javac] Compiling 3 source files to /home/benoitf/workspace/easybeans/output/example-classes install.persistence: install.war: install: [copy] Copying 2 files to /home/benoitf/workspace/easybeans/ejb3s/mdb.jar [jar] Building jar: /home/benoitf/workspace/easybeans/clients/client-mdb.jar init: compile: [javac] Compiling 5 source files to /home/benoitf/workspace/easybeans/output/example-classes install.persistence: install.war: install: [copy] Copying 4 files to /home/benoitf/workspace/easybeans/ejb3s/security.jar [jar] Building jar: /home/benoitf/workspace/easybeans/clients/client-security.jar BUILD SUCCESSFUL Total time: 8 secondsThe examples are copied under the
ejb3s/
folder of the project and are
available for the deployment.
![]() | Note |
---|---|
If the EasyBeans server is running, it will detect these new applications and deploy them automatically. |
Each example has its own build.xml
file; this
allows each example to be run independently.
The build.xml
file for this example is
located in the examples/statelessbean
folder.
This example is a stateless session bean. It contains a
helloWorld()
method that displays text on the
server side. Additionally, it demonstrates the use of EJB3 annotation,
such as @Stateless.
The trace()
method is annotated with
@AroundInvoke EJB3 annotation. This method
will be called at each call on a business method. The business methods
are defined in the interface implemented by the SessionBean
class.
The signature of the method annotated by @AroundInvoke when it is defined in the bean class, must follow this signature:
(private|protected|public) Object methodName(InvocationContext invocationContext)
throws Exception;
![]() | Note |
---|---|
As a new feature of EJB3, the bean's interface does not need to extend the Remote interface. |
If the server is not available, it must be run by following the steps described in Chapter 3, "Running the EasyBeans Server."
The stateless session bean must be deployed. If the bean has
been installed in the ejb3s
folder, this is done automatically.
On the server side, the following output should display:
[java] INFO: Creating container for archive /home/benoitf/workspace/easybeans/ejb3s/stateless.jar. [java] INFO: Analyze elapsed during : 95 ms [java] INFO: Binding bean XXX with interface XXX into registry with jndi name XXX [java] INFO: Enhancement elapsed during : 105 ms [java] INFO: Container started in : 274 ms
Once this information is displayed on the screen, the container is ready to receive client calls.
Once the container has been started, the client can be launched.
Run the client with the following ant command: ant run.client
If the client runs successfully, the following output is displayed:
[java] Calling helloWorld method... [java] Add 1 + 2... [java] Sum = '3'.
![]() | Note |
---|---|
In the client's code, the use of the PortableRemoteObject.narrow() call is no longer required. |
The build.xml
file for this example is
located in the examples/statefulbean
folder.
This is an example of a stateful session bean using the
SessionSynchronization
interface.
It uses the @Stateful annotation and uses the default transaction model, which is REQUIRED.
If the server is not available, it must be run by following the steps described in Chapter 3, "Running the EasyBeans Server."
The stateful session bean must be deployed. It is done
automatically if the bean has been installed in the ejb3s
folder.
On the server side, the following output should be seen:
[java] INFO: Creating container for archive /home/benoitf/workspace/easybeans/ejb3s/stateful.jar. [java] INFO: Analyze elapsed during : 89 ms [java] INFO: Enhancement elapsed during : 76 ms [java] INFO: Binding bean XXX with interface XXX into registry with jndi name XXX [java] INFO: Container started in : 251 ms
Once this information is displayed on the screen, the container is ready to receive client calls.
Once the container has been started, the client can be launched.
Run the client with the following ant command: ant run.client
If the client runs successfully, the following output is displayed:
[java] Start a first transaction [java] First request on the new bean [java] Second request on the bean [java] Commit the transaction [java] Start a second transaction [java] Buy 50 amount. [java] Rollback the transaction [java] after rollback, value = 30 [java] Request outside any transaction [java] Check that value = 30 [java] ClientStateful OK. Exiting.
The build.xml
file for this example is
located in the examples/entitybean
folder.
This is an example of an entity bean. It describes how to use the new Java Persistence Model of an EJB3 persistence provider. To access EJB3 entities that are POJO, a stateless session bean is used. It is a facade bean.
The Entity class is a POJO class annotated with @Entity. The entities class is managed by the persistence provider.
Currently, the persistence provider is supplied by the Hibernate product, but the ObjectWeb Speedo product should be available soon. Users will have the choice between providers.
This example uses the @Stateful annotation and uses the default transaction model, which is REQUIRED.
The example shows an entity bean using EJB3 Hibernate-prototype persistence provider.
If the server is not available, it must be run following the steps described in Chapter 3, "Running the EasyBeans Server."
The entity bean must be deployed. It is done automatically if
the bean has been installed in the ejb3s
folder.
On the server side, the following output should be seen:
[java] INFO: Creating container for archive /home/benoitf/workspace/easybeans/ejb3s/entitybean.jar. [java] INFO: Analyze elapsed during : 95 ms [java] INFO: Enhancement elapsed during : 102 ms [java] INFO: No persistence provider was set, set to value org.hibernate.ejb.HibernatePersistence. [java] INFO: Hibernate 3.1.1 [java] INFO: Using provided datasource [java] INFO: RDBMS: HSQL Database Engine, version: 1.8.0 [...] [java] INFO: Binding bean XXX with interface XXX into registry with jndi name XXX [java] INFO: Container started in : 2010 ms
Once this information is displayed on the screen, the container is ready to receive client calls.
Once the container has been started, the client can be launched.
The client is run with the following ant command: ant run.client
If the client runs successfully, the following output is displayed:
[java] Employee with id 1 = Florent [java] Employee with id 2 = Whale
These properties are defined in the
META-INF/persistence.xml
file.
By default, the dialect used to communicate with the database is set to HSQL, as it is embedded in EasyBeans.
This dialect configuration is done with the following properties:
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> <property name="toplink.target-database" value="HSQL"/>
By default, the tables are created and the database is empty after loading the entity beans.
This configuration is done with the following properties:
<property name="hibernate.hbm2ddl.auto" value="create-drop"/> <property name="toplink.ddl-generation" value="drop-and-create-tables"/>
In order to keep data in the database, this property should be changed.
The build.xml
file for this example is
located in the examples/security
folder.
This example illustrates the use of different Java EE 5.0 annotations which are linked to the security part.
The annotations used by the example are:
@DeclareRoles, which is used to declare the roles used by an EJB component
@RolesAllowed, which lists the authorized roles in order to call a method
@DenyAll, which denies the call to the method (for every role)
@RunAs, which sets a new identity when calling other EJBs
If the server is not available, it must be run following the steps described in Chapter 3, "Running the EasyBeans Server."
The security bean example must be deployed. It is done
automatically if the bean has been installed in the ejb3s
folder.
On the server side, the following output should display:
[java] 10/16/06 5:24:50 PM (I) ContainersMonitor.scanNewContainers : Creating container for archive /home/benoitf/workspace/easybeans/ejb3s/security.jar. [java] 10/16/06 5:24:50 PM (I) JContainer3.start : Analyze elapsed during : 124 ms [java] 10/16/06 5:24:50 PM (I) JContainer3.start : Enhancement elapsed during : 99 ms [java] 10/16/06 5:24:50 PM (I) JContainer3.start : Container started in : 363 ms [java] 10/16/06 5:24:50 PM (I) ContainersMonitor.scanNewContainers : Creating container for archive /home/benoitf/workspace/easybeans/ejb3s/mdb.jar. [java] 10/16/06 5:24:50 PM (I) JContainer3.start : Analyze elapsed during : 4 ms [java] 10/16/06 5:24:51 PM (I) JContainer3.start : Enhancement elapsed during : 287 ms [java] 10/16/06 5:24:51 PM (I) JContainer3.start : Container started in : 544 ms
Once this information is displayed on the screen, the container is ready to receive client calls.
Once the container has been started, the client can be launched.
The client is run with the following ant command: ant run.client
If the client runs successfully, the following output is displayed on the client side:
run.client: [java] Oct 16, 2006 5:27:03 PM org.objectweb.carol.util.configuration.ConfigurationRepository init [java] INFO: No protocols were defined for property 'carol.protocols', trying with default protocol = 'jrmp'. [java] Calling methods that everybody can call... [java] Call a bean with run-as in order to have 'admin' role... [java] Access denied as expected (method is denied)
The following output is displayed on the server side:
[java] someRolesAllowed() called [java] -> Caller is 'Principal[EasyBeans/Anonymous]'. [java] for run-as bean, caller is Caller is 'Principal[EasyBeans/Anonymous] [java] onlyAdminAllowed() called [java] -> Caller is 'Principal[admin]'. [java] someRolesAllowed() called [java] -> Caller is 'Principal[admin]'.
Table of Contents
Contributions should follow the EasyBeans code convention. A good document to begin with is Java code convention. Other conventions are also listed in this document.
In addition, EasyBeans uses tools to check the compliance: the checkstyle plugin and the eclipse checkstyle plugin. The configuration settings are available on EasyBeans SVN.
All files should have a header that contains the LGPL and the date.
If a file is modified, the modification year should be appended to the existing year, which is the year it was initially created. For example, if the create date is '1999' or '2004' it should be edited to '1999-2006' or '2004-2006', respectively.
Also, the tag $Id: code_convention.xml 314 2006-04-04 09:39:43Z pinheirg $ should be added. The following is a header example:
/** * EasyBeans * Copyright (C) 2006 Bull S.A.S. * Contact: easybeans@objectweb.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * -------------------------------------------------------------------------- * $Id: code_convention.xml 825 2006-07-06 22:45:26Z kburgess $ * -------------------------------------------------------------------------- */
Imports should reference a valid class name, instead of using wildcard imports. Wildcard imports are not authorized.
For example, if the classes List and ArrayList are used, the imports should not be as follows:
import java.util.*;
The imports should have each class as follow:
import java.util.List; import java.util.ArrayList;
The classes should not have an unused import.
![]() | Note |
---|---|
The Eclipse IDE provides facilities to do this job. There is the option Organize Imports (Shift+Ctrl+O) in the menu Source that correctly inserts the imports and removes the unused imports. However, this option does not work well with 'import static'. |
The class and interface names should begin with an uppercase letter. Also, each class and interface has an @author tag in the comment. For example:
/** * This is an example that shows a class/interface declaration. * @author Gisele Pinheiro Souza * @author Eduardo Studzinski Estima de Castro */ public class ClassExample implements InterfaceExample{ }
The space character is used instead of the tab character. The number of spaces for an indent is 4 spaces.
Wrapping a single source line into multiple lines should follow the Java code convention.
Any trailing spaces should be removed. Eclipse provides a plugin that removes the trailing spaces and converts the tab into spaces. The plugin is AnyEdit.
Use whitespaces in for() loop, while(), when concatenating strings. One space should be added before the operator and another after the operator. For example, the correct syntax is:
for (int i = 0; i < arTest.length; i++) { String strResult = "The element " + i + " has the value " + arTest[i]; }
The following code does not adhere to the convention:
for (int i = 0; i< arTest.length; i++) { String strResult = "The element "+ i+" has the value "+arTest[i]; }
All methods and attributes (including protected and private) must have a comment. The parameters, the exceptions thrown, and the method return should have a comment in the method comment. For example:
/** * This is an example that is used in the EasyBeans Code Convention. */ private int intValue; /** * This is an example method to show a class comment. * @param a an example of parameter. * @param b other example of parameter. * @return the method result. * @throws Exception the exception thrown by the method. */ public int add(final int a, final int b) throws Exception { return a + b; }
Braces must be used in the if/else blocks, even if there is a single statement. To illustrate:
if (true) { doThis(); }
The following is not allowed:
if (true) doThis();
The position of the braces should be the same as in the first example. The following format is incorrect:
if (true) { test1(); test2(); }
All exceptions require a statement; no silent catching is allowed. For example:
try { doThis(); } catch (Exception e) { // should not occur }
A logger can be used:
try { doThis(); } catch (Exception e) { logger.logDebug("Exception while doing .....", e); }
Inline conditionals are not allowed. The following code is incorrect:
b = isOk() ? true : false;
The correct way to write this is as follows:
if (isOk()) { b = true; } else { b = false; }
Declarations are static final, not final static. This is a JLS recommendation.
Constants should be static and final, and should adhere to the following:
'^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$'
Constants must be used in the code and magic number must be avoided. For example, the following is not allowed:
private int myAttribute = 5;
The correct format is:
/** * Default value */ private static final int DEFAULT_VALUE = 5; /** * This attribute is initialized with the default value */ private int myAttribute = DEFAULT_VALUE;
Table of Contents
Developers wanting to contribute information about EasyBeans can share their thoughts via the easybeans mailing list.
The steps necessary for subscribing to the list are described at the following url :http://www.objectweb.org/wws/info/easybeans
There are many ways to contribute to easybeans. New ideas are also welcome.
The following is a list of some of the ways to make contributions:
Documentation: Improve or add to the existing documentation, create new chapters, translate, etc.
Code: Some glue could be added so that EasyBeans could be integrated in other servers.
Tests: Add new tests to the current test suite.