If your EJB knowledge is sketchy or you want more information about EJB development before you begin using JBuilder's EJB wizards and tools, start reading the "Developing session beans" chapter and the chapters that follow it before beginning this chapter.
Developing Enterprise JavaBeans with JBuilder has several steps:
You can also use JBuilder to create entity enterprise beans based on existing tables in any database accessible through JDBC. See "Creating enterprise beans with the EJB Entity Modeler."
To set up JBuilder to target one or more application servers,
/Inprise/AppServer
. You must perform this step even if your target application server is some other than the Inprise Application Server.
When you close the dialog box, an IAS 4.1 library is created for you automatically that contains all the IAS files you will need for EJB development.
You must close and then restart JBuilder to enable the EJB wizards. If you want to make the VisiBroker ORB available to JBuilder, you can wait until you complete that step before shutting down and restarting JBuilder.
Next you must add a library that contains your application server files to your project. If you are targeting the Inprise Application Server, follow these steps:
If you are targeting the WebLogic Server, you must first create a new library composed of the JAR files in the WebLogic lib
directory and then add the new library to your project. For information about creating a new library, see "Creating and managing projects" in Building Applications with JBuilder.
/Inprise/AppServer/bin
directory
The Select A Different Library box appears.
As an alternative, you could create a new library named whatever you like and specify that just the /Inprise/AppServer/lib/VBJORB.JAR is in it. For information about creating new libraries, see "Creating and managing projects" in Building Application with JBuilder.
You must now shut down and restart JBuilder to enable the CORBA wizards.
The final step to make the ORB available to JBuilder is to start the SmartAgent. Choose Tools|VisiBroker SmartAgent.
The EJB 1.1 choice is a generic option. Select it if the application server you use is not currently supported by JBuilder. You will probably want to edit the resulting deployment descriptor with tools supplied with that application server to get the exact settings you want. You could also choose this option if the you aren't targeting a specific application server.
Once you have an EJB group and have edited it to your liking with the Deployment Descriptor editor, you can Make or Build an EJB group to produce the JAR. JBuilder uses the deployment descriptor to help identify the class files to be packaged.
You can have more than one EJB group in a project. All the EJB groups in a single project use the same project classpath and JDK, and they are configured for the same target application server.
If you haven't created your enterprise beans yet, begin by creating an empty EJB group. To create an empty EJB group,
JBuilder entered a default name that is the same as the name of your EJB group. You can simply accept that name or specify another.
If you already have existing IAS enterprise beans, add them to an EJB group by following these steps:
JBuilder entered a default name that is the same as the name of your EJB group. You can simply accept that name or specify another.
If you don't have an open project before you begin an EJB group wizard, JBuilder displays the Project wizard first. After you create a new project, the EJB wizard you selected then appears.
To begin creating an enterprise bean,
The wizard appears.
If you don't have an EJB group defined before you start the Enterprise JavaBeans wizard, click the New button to start the Empty EJB Group wizard. You must have at least one EJB group defined in your project before you can create an enterprise bean. Once you've created an EJB group with the Empty EJB Group wizard, select it and choose Next to continue with the Enterprise JavaBean wizard.
Next you must decide whether you are creating a session bean or an entity bean.
If you are creating a session bean,
For more information about session bean types, see ""Types of session beans" in the "Developing session beans" chapter.
SessionSynchronization
interface by checking the Session Synchronization check box.
For information about the SessionSynchronization
interface, see "The SessionSynchronization interface" in the "Developing session beans" chapter.
If you are creating an entity bean,
For information about bean-managed and container-managed persistence, see "Persistence and entity beans in the "Developing entity beans" chapter.
After you click the Finish button, JBuilder creates the bean class and its home and remote interfaces. You'll see them appear in the project pane. Examine the source code of the bean class and you'll see that the class implements the SessionBean
interface if it's a session bean, and it implements the EntityBean
interface if it's an entity bean. JBuilder has added methods with empty bodies for the methods all enterprise beans must implement. You can add code to these method bodies to supply the logic your bean requires when these methods are called.
The home interface extends the EJBHome
interface and contains a create()
method needed to create the bean. The remote interface extends EJBObject
but is empty otherwise because you have yet to declare any business logic methods for your bean.
If you need to add properties to the bean, you can either add them directly in the source code, or you can use the Properties page of the Bean designer.
To use the Bean designer to work with properties,
To add a new property,
JBuilder adds the new property to the source code of your bean.
If you used the Enterprise JavaBean wizard to begin an entity bean with container-managed persistence, you will be adding properties to your bean. Keep in mind that one of properties must be the primary key and that you must specify which field is the primary key on the Persistence panel of the Deployment Descriptor editor. If you fail to do so, the Deployment Descriptor won't be able to verify the deployment descriptor as valid.
You can also use the Properties page to modify the property. For example, if you didn't specify a setter for your property when you were declaring it and you decide your bean needs one, you can simply check the Setter box for that property on the Properties page and JBuilder adds the setter method to your source code. Or you can remove a getter or setter by unchecking the appropriate check box.
To remove a property from your bean using the Properties page,
JBuilder asks if you want to remove the property and its associated code.
You can also use the Properties page to change the name of the property and its type. The Bean designer is a two-way tool, so changes you make on the Properties page are reflected in your code and changes you make in your code are reflected by what you see on the Properties page.
To add methods to the remote interface,
As you check methods in the Methods box, the methods are added to the remote interface.
To remove a method from the remote interface, uncheck the check box next to the method in the Methods box.
To edit one of the methods, right-click it to display a context menu and choose Edit Selected. The file opens in the code editor and your cursor is positioned on that method, ready for you to edit it.
The context menu has other commands you'll find useful. You can choose Remove Selected to remove a method from the bean class. Choosing Check All checks all the methods so that they are all added to the remote interface; checking Uncheck All unchecks all the methods so that no methods are added to the remote interface.
You can use the Methods page to verify that the methods declared in your bean class have the same method signature as they do in the home and remote interface. For example, suppose you add a parameter to the ejbCreate()
method in your bean class, but neglect to add it to the create()
method in the home interface. The Methods box will show both the ejbCreate()
method and create()
method in red text. If you then click a method displayed in red text, the Problem Description box explains what the problem is. You could then add the additional parameter to the create()
method to make the method signatures match and fix the problem. Or, if you remove methods from your bean class but forget to do so in the remote interface, the Methods box will display those methods in red text to remind you to remove them from the remote interface.
To use the EJB Interfaces wizard,
To change the build properties to generate and add client stubs to your classpath (this step is optional),
You can also modify the build properties for an EJB group:
You can change the name of the output JAR file and where it is generated.
If you don't want to use JBuilder's Deployment Descriptor editor to edit the deployment descriptors, but want to use another tool to edit the deployment descriptors, uncheck the Include Deployment Descriptors in Output Jar File option. The JAR file that is created won't include the deployment descriptors in it.
You can also import deployment descriptors into or export deployment descriptors out of the EJB group.
If you want to specify that additional files should be added to the JAR file, click the Add Button and specify the location of the files. You'll need to do this if you've added a new class, for example, to your project and you want it become part of the JAR file.
If you are targeting the WebLogic Server, you can choose to use the WebLogic ejbc.exe, which creates another JAR file that contains the compiled stub files from the EJB group JAR file. This new JAR file is then ready to deploy. Choose Project Properties|Build and select the WebLogic tab (this tab appears only if WebLogic is a target application server). For more information, click the Help button in the dialog box.
To compile all the classes in the project, right-click the project file (<project>.jpx) and choose Make, or simply choose Project|Make Project.
During the compiling process, JBuilder might detect that a problem exists in a deployment descriptor that makes it invalid. If this happens, you'll see a message appear in the message pane that tells you to verify the bean in the Deployment Descriptor editor. For more information about verifying a deployment descriptor, see "Verifying descriptor information."
Note for WebLogic users. If you are targeting the WebLogic Server, you'll receive an error during the build process if the temporary directory or the classpath contains embedded spaces, such as C:/Documents and Settings/jbprojects.
If you've chosen to generate the clients stubs, you'll see that the home interface node in the project pane now has several files listed below it if you click its icon to expand it. These generated files are the required client stubs and helper classes that make EJB work.
When you compile your project, JBuilder creates a JAR file based on the configured name and displays it as a node under the group in the project pane.
You can also create the JAR file without compiling your entire project. Right click the EJB group node in the project pane and choose Make to compile the EJB group node. If you want to modify the build properties before choosing Make, select the Properties menu item on the same popup menu and make any modifications you want in the Build Properties dialog box before choosing Make to generate the JAR file.
The JAR file contains all the deployment descriptors. Each deployment descriptor is an XML file. Each JAR file can contain one or more deployment descriptors.
JBuilder will target multiple application servers. The application server you are targeting determines the number of deployment descriptors that are in the generated JAR file. Every JAR file will have an ejb-jar.xml
, which describes the deployment attributes for the beans in the group that are common among all application servers. ejb-jar.xml
is the EJB 1.1-compliant deployment descriptor. If you have selected EJB 1.1 as your target application server, that is the only deployment descriptor that JAR file will contain.
Other targeted application servers will have one or more application server-specific XML files. If the Inprise Application Server is your target, there will be just one application server-specific XML file, ejb-inprise.xml
. If the WebLogic Application Server is your target, the generated JAR file requires an ejb-jar.xml
file, a weblogic-ejb-jar.xml
file, and one additional XML file for each entity bean with container-managed persistence.
JBuilder's Deployment Descriptor editor provides a way to modify the existing Inprise deployment descriptors.
To display the Deployment Descriptor editor, double-click the EJB group in the project pane. The Deployment Descriptor editor appears. Note that a tree of the EJB group appears in the structure pane.
To view information about an enterprise bean in the deployment descriptor editor, click the bean in the structure pane. Or if you select the EJB Deployment Descriptor node in the structure pane, you can click the Contents tab to display the contents of the EJB group and then double-click the icon of bean you want to view. When a bean is selected in the editor, several tabs appear in the Deployment Descriptor editor. You use these tabs to go to panels where you edit deployment descriptor information.
For detailed information about using the Deployment Descriptor editor, see "Using the Deployment Descriptor editor."
After you've finished editing the descriptor, you can verify the file to make sure the descriptor information correct, the required bean class files are present, and so on.
To verify descriptor information, click the Verify button on deployment descriptor's tool bar.
Verify does the following:
If the verification fails, one or more messages appear in a Log panel describing the failures.
With JBuilder 4.0, these deployment descriptors are gathered into a single EJB group file. The result is you can now have multiple EJB groups per project. It also permits the build system to create the deployable JAR files without needing a META-INF directory or even requiring you to use a deployment wizard. This also makes it possible for the build system to create proprietary deployment descriptors based upon the application server you are targeting. JBuilder adds support for multiple application servers through OpenTools API components. Third parties can also use the OpenTools API to add support for additional application servers.
Once you've used the EJB Entity Bean Modeler to generate the code that makes up the entity beans, their primary keys, their home and remote interfaces, and the appropriate entries in the deployment descriptor, you can then modify the results using other JBuilder tools, such as the Bean designer, the Deployment Descriptor editor, and the JBuilder code editor.
To display the Entity Modeler, choose File|New, click the Enterprise tab, and choose EJB Entity Bean Modeler. If you have at least one EJB group defined in your project, the Entity Bean Modeler appears.
All enterprise beans developed with JBuilder must belong to an EJB group. If you don't have at least one EJB group in your current project, click the New button to start the Empty EJB Group wizard. Once you've created an EJB Group with the Empty EJB Group wizard, the Entity Bean Modeler then appears.
To create one or more beans from existing database tables, follow these steps:
The EJB group you select is used to determine where the deployment information is written.
Enter the information that's needed to connect to a JDBC data source.
To use an existing connection, click the Choose Existing Connection button and select a connection. Other required information for this page is then filled in automatically except the password, which you must enter yourself if your connection requires one.
If you don't have an existing connection or want to create another, select a driver from the Driver drop-down list and specify an URL.
Specify the Username for the data source, and if a password is required, type in the password. Select any extended properties you need. Finally, specify a JNDI name for the data source and choose Next.
The EJB Entity Bean Modeler attempts to connect to the specified data source. Only if the connection is successful does the next page appear.
For each table you select, one entity bean will be created. From the Available list select the tables you want and move them to the Select list by using the > and >> buttons. When you've selected all your tables, choose Next.
In the Tables and Links section, you'll see all the tables you selected in the previous step. Select each table in turn by clicking on it and then use the Selected Table's Columns section to move any columns of the table between the Available and Selected lists. By default, all columns in every table are selected.
You can also specify relationships between the tables by dragging the mouse pointer between the tables in the Tables and Links box on the left. Or you can use the Add Link button to do the same thing. When you use either method, a dialog box appears that proposes a relationship based on foreign keys, primary keys, unique indexes, and field names and types in the two tables. You can accept the suggested relationship or modify it to create the relationship you want. To remove a link between tables, choose Remove Link.
Don't specify any relations if you want entity beans with bean-managed persistence, because the Entity Bean Modeler won't generate entity beans with bean-managed persistence if relations are specified.
Here's an example of three tables linked together:
When you've selected all columns in each table that you want mapped to fields in entity beans you're creating, choose Next.
From the Table drop-down list, select the table you want to begin the mapping process on. For each column in the table a suggested Field Name and Field Type appears. You can simply accept the suggested name or edit the suggested names and types as you want them to be in your bean.
If the table already has a primary key, that field or set of fields is selected when the Map Columns page first appears. If no primary key exists, you must select one or more fields to make up primary key by checking the check box for those fields in the Primary Key column. When you finish mapping all the selected columns to the field names and types you want in your entity bean for each table, choose Next.
For each table in the Tables list, JBuilder suggests a name for the entity bean class, the name of the home and remote interfaces, the name of the primary key class, and the name used by JNDI. You can accept these names as they are, or you can modify them as you wish. When you have finished specifying the information for each table, choose Next.
findAll()
method added to their home interfaces, check that option. You can also choose whether you want header comments to appear in the resulting files. If you want to prepare for EJB 2.0 and want the code generated to follow the EJB 2.0 style, select the EJB 2.0 code style option. For more information about these options, choose the Help button in the Entity Modeler.
If you target application server is the WebLogic Application Server and you are creating an entity bean with container-managed persistence, this page also includes a Pool Name field in which you should enter the name of the pool for your CMP WebLogic beans:
JBuilder creates an entity bean for each table and all the supporting classes interfaces. You can now add the business logic you want to add to the beans, define the methods you want the client to be able to call in the remote interface, compile the beans, and edit the deployment descriptors for the beans.
To create a test client application,
Option | Description |
Generate Logging Messages | Adds code that displays messages reporting on the bean's status as the client runs. For example, a message is displayed when bean initialization is begun and another when it completes. This option also generates wrappers for all the methods declared in the home and remote interfaces and initialization functions. Finally, the messages report how long each method call takes to complete. |
Generate Main Function | Adds the main function to the client. |
Generate Header Comments | Adds header comments to the client. |
Your test client application will look something like this if you selected the Generate Logging Messages and the Generate Main Function options:
package AnotherProject; import javax.naming.*; import javax.rmi.PortableRemoteObject; public class EmployeeTestClient1 { private static final String ERROR_NULL_REMOTE = "Remote interface reference is null. It must be created by calling one of the Home interface methods first."; private static final int MAX_OUTPUT_LINE_LENGTH = 50; private boolean logging = true; private EmployeeHome employeeHome = null; private Employee employee = null; /**Construct the EJB test client*/ public EmployeeTestClient1() { long startTime = 0; if (logging) { log("Initializing bean access."); startTime = System.currentTimeMillis(); } try { //get naming context Context ctx = new InitialContext(); //look up jndi name Object ref = ctx.lookup("Employee"); //cast to Home interface employeeHome = (EmployeeHome) PortableRemoteObject.narrow(ref, EmployeeHome.class); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded initializing bean access."); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed initializing bean access."); } e.printStackTrace(); } } //---------------------------------------------------------------------------- // Methods that use Home interface methods to generate a Remote interface reference //---------------------------------------------------------------------------- public Employee create(Short empNo, String firstName, String lastName, String phoneExt) { long startTime = 0; if (logging) { log("Calling create(" + empNo + ", " + firstName + ", " + lastName + ", " + phoneExt + ")"); startTime = System.currentTimeMillis(); } try { employee = employeeHome.create(empNo, firstName, lastName, phoneExt); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: create(" + empNo + ", " + firstName + ", " + lastName + ", " + phoneExt + ")"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: create(" + empNo + ", " + firstName + ", " + lastName + ", " + phoneExt + ")"); } e.printStackTrace(); } if (logging) { log("Return value from create(" + empNo + ", " + firstName + ", " + lastName + ", " + phoneExt + "): " + employee + "."); } return employee; } public Employee create(Short empNo) { long startTime = 0; if (logging) { log("Calling create(" + empNo + ")"); startTime = System.currentTimeMillis(); } try { employee = employeeHome.create(empNo); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: create(" + empNo + ")"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: create(" + empNo + ")"); } e.printStackTrace(); } if (logging) { log("Return value from create(" + empNo + "): " + employee + "."); } return employee; } public Employee findByPrimaryKey(Short primaryKey) { long startTime = 0; if (logging) { log("Calling findByPrimaryKey(" + primaryKey + ")"); startTime = System.currentTimeMillis(); } try { employee = employeeHome.findByPrimaryKey(primaryKey); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: findByPrimaryKey(" + primaryKey + ")"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: findByPrimaryKey(" + primaryKey + ")"); } e.printStackTrace(); } if (logging) { log("Return value from findByPrimaryKey(" + primaryKey + "): " + employee + "."); } return employee; } //---------------------------------------------------------------------------- // Methods that use Remote interface methods to access data through the bean //---------------------------------------------------------------------------- public Short getEmpNo() { Short returnValue = null; if (employee == null) { System.out.println("Error in getEmpNo(): " + ERROR_NULL_REMOTE); return returnValue; } long startTime = 0; if (logging) { log("Calling getEmpNo()"); startTime = System.currentTimeMillis(); } try { returnValue = employee.getEmpNo(); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: getEmpNo()"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: getEmpNo()"); } e.printStackTrace(); } if (logging) { log("Return value from getEmpNo(): " + returnValue + "."); } return returnValue; } public String getFirstName() { String returnValue = ""; if (employee == null) { System.out.println("Error in getFirstName(): " + ERROR_NULL_REMOTE); return returnValue; } long startTime = 0; if (logging) { log("Calling getFirstName()"); startTime = System.currentTimeMillis(); } try { returnValue = employee.getFirstName(); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: getFirstName()"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: getFirstName()"); } e.printStackTrace(); } if (logging) { log("Return value from getFirstName(): " + returnValue + "."); } return returnValue; } public void setFirstName(String firstName) { if (employee == null) { System.out.println("Error in setFirstName(): " + ERROR_NULL_REMOTE); return ; } long startTime = 0; if (logging) { log("Calling setFirstName(" + firstName + ")"); startTime = System.currentTimeMillis(); } try { employee.setFirstName(firstName); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: setFirstName(" + firstName + ")"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: setFirstName(" + firstName + ")"); } e.printStackTrace(); } } public String getLastName() { String returnValue = ""; if (employee == null) { System.out.println("Error in getLastName(): " + ERROR_NULL_REMOTE); return returnValue; } long startTime = 0; if (logging) { log("Calling getLastName()"); startTime = System.currentTimeMillis(); } try { returnValue = employee.getLastName(); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: getLastName()"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: getLastName()"); } e.printStackTrace(); } if (logging) { log("Return value from getLastName(): " + returnValue + "."); } return returnValue; } public void setLastName(String lastName) { if (employee == null) { System.out.println("Error in setLastName(): " + ERROR_NULL_REMOTE); return ; } long startTime = 0; if (logging) { log("Calling setLastName(" + lastName + ")"); startTime = System.currentTimeMillis(); } try { employee.setLastName(lastName); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: setLastName(" + lastName + ")"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: setLastName(" + lastName + ")"); } e.printStackTrace(); } } public String getPhoneExt() { String returnValue = ""; if (employee == null) { System.out.println("Error in getPhoneExt(): " + ERROR_NULL_REMOTE); return returnValue; } long startTime = 0; if (logging) { log("Calling getPhoneExt()"); startTime = System.currentTimeMillis(); } try { returnValue = employee.getPhoneExt(); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: getPhoneExt()"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: getPhoneExt()"); } e.printStackTrace(); } if (logging) { log("Return value from getPhoneExt(): " + returnValue + "."); } return returnValue; } public void setPhoneExt(String phoneExt) { if (employee == null) { System.out.println("Error in setPhoneExt(): " + ERROR_NULL_REMOTE); return ; } long startTime = 0; if (logging) { log("Calling setPhoneExt(" + phoneExt + ")"); startTime = System.currentTimeMillis(); } try { employee.setPhoneExt(phoneExt); if (logging) { long endTime = System.currentTimeMillis(); log("Succeeded: setPhoneExt(" + phoneExt + ")"); log("Execution time: " + (endTime - startTime) + " ms."); } } catch(Exception e) { if (logging) { log("Failed: setPhoneExt(" + phoneExt + ")"); } e.printStackTrace(); } } //---------------------------------------------------------------------------- // Utility Methods //---------------------------------------------------------------------------- private void log(String message) { if (message.length() > MAX_OUTPUT_LINE_LENGTH) { System.out.println("-- " + message.substring(0, MAX_OUTPUT_LINE_LENGTH) + " ..."); } else { System.out.println("-- " + message); } } /**Main method*/ public static void main(String[] args) { EmployeeTestClient1 client = new EmployeeTestClient1(); // Use the client object to call one of the Home interface wrappers // above, to create a Remote interface reference to the bean. // If the return value is of the Remote interface type, you can use it // to access the remote interface methods. You can also just use the // client object to call the Remote interface wrappers. } }
The EJB Test Client wizard generates a test client that creates a reference to the enterprise bean.
If the Generate Logging Messages option is selected, for each method declared in the bean's remote interface, the wizard also declares and implements a method that calls the remote method. Each of these methods reports its success in invoking the remote method and how long the remote method took to execute.
You have a couple of different ways to use the generated test client application. If you added a main()
function to the test client application, you can write the code that invokes the calls to the enterprise bean's methods in the main()
function. You do this by first calling either a create or find method, and, if a remote reference is returned, by using that remote reference to call the bean's business methods. Or, because the wizard has declared a client object in the main()
function, you can use that client object to simply call the methods declared in the test client application that call the bean's remote methods.
If you prefer to write the logic that calls each of the business methods from another class, you can choose to create and use an instance of the test client application. See Using the test client application.
If this option isn't checked, when you click Next, the EJB Test Client wizard starts. When you are through using it, the Use EJB Test Client wizard resumes.
The wizard adds a declaration of the test client application you specified to the class like this, for example:
EmployeeTestClient1 employeeTestClient1 = new EmployeeTestClient1();
Now you're ready to call the methods declared in the test client application.
To create a Server configuration,
To create a Client configuration,
main()
function that calls the methods of the test client.
Now you're ready to start the container. Select the Server run configuration from the drop-down list next to the Run button on the JBuilder toolbar. The container starts up. Be patient as the start-up process takes a while. You can view the progress of the start-up process in the message window. Any errors that occur will also appear there.
Next select the Client run configuration to run your client application. The messages that appear in the message window report the success or failure of the client application's execution.
Another way to test your bean is to simply right-click its EJB group and choose Run.
You can debug your enterprise beans or the client just as you would any other Java code with JBuilder. For information about debugging, see "Debugging Java programs." in Building Applications with JBuilder.