Handling remote exceptions calling Gen EJB from hand-written Java
search cancel

Handling remote exceptions calling Gen EJB from hand-written Java

book

Article ID: 25535

calendar_today

Updated On:

Products

Gen Gen - Run Time Distributed

Issue/Introduction

Calling a Gen generated EJB directly from a hand-written Java (client) application requires adding some additional code to handle unexpected problems when processing server logic.

Environment

Gen EJB had written call.

Resolution

It is important to remember that invoking a Gen generated EJB directly from a hand-written Java application requires adding some additional code to handle unexpected problems encountered when processing server logic.
Various problems accessing a database like deadlock, missing or unimplemented table, are examples of such unexpected conditions.
The Gen generated client handles these conditions automatically. The Gen runtime prepares suitable error message, client logic is interrupted and the error message dialog box is displayed.

Ignoring these exceptions in a hand written situation can be confusing for the end user who may not be aware that certain changes in the database have been rolled back and the transaction was not successfully completed.

A RemoteException class is the common superclass for a number of communication-related exceptions that may occur during the execution of a remote method call. Each method of a remote interface, an interface that extends java.rmi.Remote, must list RemoteException in its throws clause.

The general purpose of this class is to provide an exception-chaining mechanism and allows wrapping messages returned by other classes and their methods. For example, the Gen runtime stores error message returned by the JDBC classes responsible for the execution of the SQL in the generated EJB.

Here are two different example messages returned during processing two different JDBC drivers:

Oracle (deadlock):

ERROR MYSERV @0000000016,0009400214,16 0 [FEDB/0] [BEA][Oracle JDBC Driver][Oracle]ORA-00060: deadlock detected while waiting for resource 

MSSQL 2005 (missing table)

ERROR MYSERV@0000000001,0000000021,1 0 [FEDB/0] Table not found in statement
[SELECT MYENTITY01."TEXT0",MYENTITY01."ID" FROM "MYENTITY" MYENTITY01 WHERE MYENTITY01."ID" = ? ]
SQLSTATE: S0002
SQLCODE: -22

Extract the error message from the exception object, scan the message to retrieve relevant information and present an error message to the user. Here is some sample code showing how to invoke an EJB (installed on JBoss EAP 7.1) from the Java application and how to retrieve the error message after RemoteException exception is thrown.

package my.pack;
import java.rmi.RemoteException;
import java.util.Properties;
 
import javax.ejb.CreateException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
 
import m_17642528.MYSERV_Home;
import m_17642528.MYSERV_Remote;
import m_17642528.MyservExport;
import m_17642528.MyservImport;
 
public class InvokeEjb {
 
       private static final String PROVIDER_URL = "remote+http://hostname:8080";
       private static final String INITIAL_CONTEXT_FACTORY = "org.wildfly.naming.client.WildFlyInitialContextFactory";
 
       public static void main(String[] args) {
              InvokeEjb invokeEjb = new InvokeEjb();
              try {
                     invokeEjb.start();
              } catch (NamingException e) {
                     e.printStackTrace();
              } catch (RemoteException e) {
                     if (e.getMessage().startsWith("ERROR")) {
                           System.out.println("ERROR MESSAGE: " + e.getMessage());
                     }
              } catch (CreateException e) {
                     e.printStackTrace();
              }
       }
 
       private void start() throws NamingException, RemoteException,
                     CreateException {
              Properties properties = new Properties();
              properties.put(javax.naming.Context.PROVIDER_URL, PROVIDER_URL);
              properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
                           INITIAL_CONTEXT_FACTORY);
              Context context = new InitialContext(properties);
              MYSERV_Home home = (MYSERV_Home) PortableRemoteObject.narrow(context
                           .lookup("MYSERV"), MYSERV_Home.class);
              MYSERV_Remote remote = home.create();
              MyservImport myservImport = new MyservImport();
              myservImport.getImportMyentity().setId((short) 100);
              myservImport.getImportMyentity().setText("Mary");
              MyservExport myservExport = remote.call(myservImport);
              System.out.println("Returns: "
                           + myservExport.getExportMyentity().getId() + ", "
                           + myservExport.getExportMyentity());
       }
 
}