Diploma Thesis

Document Sample
Diploma Thesis Powered By Docstoc
					                            Diploma Thesis

    Development of a JEE Application Container for Session
                                  Beans



                            Sebastian Vogel

                          Rainer Garhammer




Fakultät:      Informatik/Mathematik

Erstprüfer:    Prof. Dr. Fritz Jobst

Zweitprüfer:   Prof. Dr. Edwin Schicker
Table of Contents

I Abstract                                                                                                                           4
                                                                                                          .
  1 English................................................................................................ ...........................4
                                                                                                                              .
  2 Deutsch..........................................................................................................................5

II Enterprise Java Beans 3.0                                                                                                         6
                                                                                                                          .
  1 Java Enterprise Edition............................................................................................ ......6
  2 Enterprise Java Beans....................................................................................................    8
                                                                                                                      .
     2.1 EJB Roles...............................................................................................................8
     2.2 EJB Types...............................................................................................................9
                                                                                                                      .
  3 Application Servers.............................................................................................. ........10

III Requirements for JSlave                                                                                                        12
  1 Functional requirements...............................................................................................12
     1.1 Session Beans....................................................................................................... 2   1
        1.1.1 Client View of a Session Bean.......................................................................12
        1.1.2 Session Bean Life Cycles..............................................................................13
     1.2 Deployment...........................................................................................................16
        1.2.1 JEE application file formats............................................................................16
        1.2.2 Deployment Process......................................................................................19
     1.3 Meta data processing............................................................................................20
                                                                                                                                  2
     1.4 Interceptors............................................................................................................ 2
                                                                                                                       .
     1.5 Remote Connections.................................................................................. ..........24
        1.5.1 Remote Method Invocation(RMI)...................................................................25
        1.5.2 Web Services.................................................................................................27
     1.6 Naming / Local Connections.................................................................................29
                                                                                                                        .
     1.7 Dependency Injection.................................................................................. .........31
                                                                                                                               .
     1.8 Security ................................................................................................................32
     1.9 Monitoring, Logging interfaces..............................................................................35
  2 Non-functional requirements........................................................................................36
  3 Further requirements according to specification..........................................................37

IV Implementation                                                                                                                  38
                                                                                                 .
  1 Structure..................................................................................... .................................38
     1.1 Overall structure....................................................................................................38
        1.1.1 Base Classes.................................................................................................38
        1.1.2 Service Classes.............................................................................................40
        1.1.3 Basic Connection and Bean classes.............................................................42
     1.2 Project structure....................................................................................................43
                                                                                                                           .
     1.3 Server folder structure................................................................................. .........44
  2 Deployment Process..................................................................................................... 6       4
     2.1 ClassLoader Delegation Hierarchy.......................................................................48
     2.2 Meta Data Processing...........................................................................................50
                                                                                                                       .
     2.3 Bean Environment.................................................................................... ............52
     2.4 Dynamic Proxy Creation........................................................................................ 3           5
  3 Connection management.............................................................................................. 7           5
                                                                                                                         .
     3.1 Client Views............................................................................................... ...........59
     3.2 Connection Tree Structure....................................................................................59
     3.3 EJBContext and SessionContext..........................................................................61
  4 Life Cycle of a Session Bean Instance.........................................................................62
     4.1 BeanInstanceManager..........................................................................................64
     4.2 Bean and Interceptor Instance Creation...............................................................65
     4.3 Life Cycle Callbacks..............................................................................................66
     4.4 Security check.......................................................................................................70
     4.5 Interceptor Stack ..................................................................................................71
  5 Distribution subsystem.................................................................................................. 2      7
                                                                                                           .
     5.1 RMI................................................................................................ .......................73
        5.1.1 RMI Customizations.......................................................................................74
        5.1.2 TRMI............................................................................................................... 5 7
        5.1.3 TRMI Customizations.....................................................................................77
        5.1.4 Authentication Extension...............................................................................78
     5.2 Web Services........................................................................................................78
                                                                                                                  .
  6 Security Subsystem.................................................................................... .................80
                                                                                                     .
  7 Multithreading................................................................................. .............................82
  8 Monitoring and Logging................................................................................................84

V Difficult hot spots                                                                                                             89
  1 Bean Environment Multiplexing....................................................................................89
  2 Code generation...........................................................................................................90
  3 RMI limitations..............................................................................................................91
                                                                                                            .
  4 Authentication ......................................................................................... ....................92

VI User guide                                                                                                                     93
                                                                                                                               .
  1 Installation....................................................................................................................93
                                                                                                .
  2 Server....................................................................................... ...................................95
                                                                                                                        .
     2.1 Startup, Shutdown.................................................................................... ............95
     2.2 Deploying applications..........................................................................................96
                                                                                                                           .
     2.3 Monitoring.............................................................................................................96
                                                                                                                      .
     2.4 Logs....................................................................................................................101
  3 Sample applications.................................................................................................... 02      1
     3.1 Hello World sample.............................................................................................103
     3.2 Course Administration Sample............................................................................104
        3.2.1 Client Application.........................................................................................106
                                                                                                           .
        3.2.2 Beans................................................................................... .......................108
  4 Coding Guidelines......................................................................................................109
                                                                                                                    .
     4.1 Coding Beans....................................................................................... ..............109
     4.2 Coding Clients.....................................................................................................110
                                                                                                               .
        4.2.1 RMI........................................................................................... ...................110
        4.2.2 Web Services.............................................................................................. .111     .

VII Limitations                                                                                                                 113
                                                                                                                        .
  1 Backwards Compatibility...................................................................................... ......113
  2 Dependability..............................................................................................................113
                                                                                                                        .
  3 Infrastructure Integration...................................................................................... ......114
  4 Scalability and Workload Balancing............................................................................115
                                                                                                                 .
  5 Incompleteness............................................................................................. .............115
     5.1 Meta Data............................................................................................................115
     5.2 SessionContext.................................................................................................... 16 1
                                                                                                                       .
     5.3 TimerService................................................................................................ .......116

VIII Bibliography                                                                                                               117
                                                                                  JSlave - Abstract"




I Abstract

1 English

The goal of this diploma thesis is the development of a JEE (Java Enterprise Edition) application
container.

The main purpose of this project is to help students to understand principles and problems of
application servers and the EJB 3.0 specification (see [ejbspec]). They should be able to analyze the
source code, see the processes going on inside the container and be able to extend the existing
architecture. There are a few application server available as Open Source (JBoss, GlassFish, etc.),
but their code structure, log files and management interfaces are mostly too complex for people who
are not directly involved in the development process of those applications.

This project was initiated and realized at the Kwantlen University College, Vancouver BC, Canada
and the University of Applied Sciences, Regensburg, Germany.

The name of the project is JSlave.




                                                 4
                                                                               JSlave - Deutsch"




2 Deutsch

Dieses Projekt befasst sich mit der Entwicklung eines JEE Anwendungs-Containers für Session
Beans.

Der Hauptzweck dieses Projekts ist es Studenten zu helfen, die Prinzipien und Probleme von
Anwendungsservern und der EJB 3.0 Spezifikation zu verstehen. Es soll ihnen ermöglicht werden,
die Quellcodes und die Prozesse im Container zu analysieren, sowie die bestehende Architektur zu
erweitern. Es gibt zwar schon einige Server, die als Open Source verfügbar sind (Jboss,
GlassFish,etc.) , aber deren Code Struktur, Logging Dateien und Management Schnittstellen sind
oftmals zu komplex für Personen, die nicht direkt in den Entwicklungsprozess eingebunden sind.

Dieses Projekt wurde gestartet und durchgeführt am Kwantlen University College in Vancouver
BC, Kanada und an der Fachhochschule Regensburg, Deutschland.

Der Name des Projekts lautet JSlave.




                                               5
                                                                  JSlave - Enterprise Java Beans 3.0"




II Enterprise Java Beans 3.0
This chapter covers the basics about Enterprise Java Beans (EJB), EJB containers, application
servers, and the Java Enterprise Edition (JEE).


1 Java Enterprise Edition

The Java Enterprise Edition is a specification that helps users to create and run enterprise
applications. Enterprise applications are defined in [Sun01], p12 as “large-scale, multi-tiered,
scalable, reliable, and secure network applications”. The functionality of an enterprise application in
the JEE specification is distributed into different tiers.


In an JEE Enterprise Application these tiers are:
    ●   Client Tier
        The client tier is the user interface of a JEE application. The client tiers is normally located
        on a different machine from the JEE server. For instance, the client can be a Swing or .NET
        application or a web browser.
    ●   Web Tier
        The web tier is part of a JEE server. It generates static html pages out of a dynamic Java
        Server Pages (JSP).
    ●   Business Tier
        The business tier holds the business logic of an enterprise application. In a JEE application
        business logic is executed within Enterprise Java Beans (EJB).
    ●   Data Tier
        Typically the data needed by an enterprise application is stored in a relational database. But
        data can also be retrieved from legacy systems or other information systems (e.g. ERP).




                                                     6
                                                                         JSlave - Java Enterprise Edition"




 Client                           Web                         Business                      Data
 Tier                             Tier                        Tier                          Tier



                                                               Application
   Client                          Web                          Container
                   HTTP           Server           RMI
                                 Servlets,                    Enterprise Java                 Data
  (Swing,
   SWT,                            JSP                            Beans          JDBC...
                                                              Session Beans                  (DB2,
   AWT,
                                                               Entity Beans                 Oracle,
  Browser)
                      RMI, WebServices, Corba                 Message Driven                Legacy)
                                                                  Beans




                                             JEE Server

Illustration 1: Java Enterprise Edition overview




                                                          7
                                                                   JSlave - Enterprise Java Beans"




2 Enterprise Java Beans

The business logic in JEE applications is provided in Enterprise Java Beans (EJB). As specified in
[ejbspec], p25 the EJB architecture “is a architecture for the development and deployment of
component-based business applications”. EJBs can be accessed and configured by open protocols
and interfaces (RMI, CORBA, SOAP) and they can access other business components (e.g. other
EJBs) in the same way, thus they can act both as a service provider and a service consumer. This
suits the needs of a Service Oriented Architecture (SOA).


2.1 EJB Roles

To import a set of Java classes (which provide the business logic of an application) into a JEE
Application Server [ejbspec], 2.2 defines a number of roles:
   ●   Enterprise Bean Provider
       “The enterprise bean provider is the producer of enterprise beans”. He decides which classes
       are united into components and which responsibility they have to take within an Enterprise
       Application. He decides about the definition of EJBs and annotates the corresponding
       classes or specifies them in the deployment descriptor. His output is an ejb-jar file that
       contains one or more EJBs, libraries and other resources.
   ●   Application Assembler
       The application server combines one or more ejb-jar files into a larger deployable unit.
       His input is one or more ejb-jar files and his output is one ore more ejb-jar files with
       special application assembling information.
   ●   EJB Server Provider / Container Provider
       The Server Provider is the actual runtime for session bean instances. The Container Provider
       is responsible for providing deployment tools and runtime support for bean instances. The
       EJB specification does not distinguish between Server Provider and Container Provider, so
       there is no special interface between them. Thus, in this document server and container are
       seen as one component.
   ●   System Administrator
       The System Administrator is responsible for configuring and administrating EJB server and



                                                  8
                                                                                     JSlave - EJB Roles"



         container.




2.2 EJB Types

[ejbspec], 2.4 defines three types of EJBs:

   ●     Session Beans

         Execute on behalf of a single client and can be transaction-aware. Are invoked
         synchronously.

   ●     Message Driven Beans

         Execute upon receipt of a single client message and can be transaction-aware. Are invoked
         asynchronously.

   ●     Entity Beans

         Provide an object view of data in a database or other information systems.

JSlave covers the implementation of a session bean container. There are two basic types of session
beans.

   ●     Stateful Session Beans

         Stateful session beans have a conversational state. All stateful beans are bound to only one
         session (one client). Because they have a state, they can store non-persistent information in
         their attributes, e.g. a list of products in a shopping cart application.

   ●     Stateless Session Beans
         Stateless session beans do not have a conversational state. They exist independently from a
         specific session. It is not guaranteed that information which is stored in the attributes of a
         stateless session bean is kept over more than one method call. Because stateless session
         beans are not suitable for storing information they are mostly used for standard tasks, e.g.
         sending mail or computing.



                                                      9
                                                                      JSlave - Application Servers"




3 Application Servers

EJB application servers represent the roles EJB Server Provider and EJB Container Provider. They
provide a runtime environment for EJBs. The main benefit of an application server is that the
software developers can focus on the business logic of an enterprise application. Routine tasks are
solved by the application server.
An application server normally provides:
   ●   deployment interfaces
   ●   access to external resources (e.g. other software components, file systems, etc.)
   ●   administration interfaces
   ●   monitoring interfaces, logs
   ●   remote connectivity
   ●   naming services
   ●   persistent access to databases
   ●   security management
   ●   transaction support


The following list shows the most important JEE application servers. Almost all of those
implementations support EJB 3.0, however the Sun Java System Application Server Platform 9 (and
GlassFish) and JEUS Application Server are the only ones that received the JEE 5 certification.
Most of them are combined with a web container and thus represent a complete JEE server.
   ●   JBoss (OpenSource)
   ●   GlassFish (Open Source, JEE 5 compatible)
   ●   Sun Java System Application Server Platform (based on GlassFish)
   ●   IBM WebSphere
   ●   BEA WebLogic
   ●   JEUS Application Server
   ●   JOnAS JEE Server (lightweight server, preferred for embedded platforms)
   ●   Apache Geronimo
   ●   SAP NetWeaver Application server




                                                 10
                                                 JSlave - Application Servers"



●   EasyBeans (standalone EJB container)
●   Apache OpenEJB (standalone EJB container).




                                           11
                                                                                JSlave - Requirements for JSlave"




III Requirements for JSlave
The main purpose of this implementation of a JEE application server is to give students an insight
in the processes that run within an application server and to give an overview of the structure and
technologies that are used.

Thus factors like performance, load balancing, EJB 2.1 support, cluster-support and 100%
specification conformity are not first priority in this project.

However the container should have sufficient logs and suitable monitoring interfaces, to show the
internal processes and the state of the container.


1 Functional requirements

1.1 Session Beans


1.1.1 Client View of a Session Bean

A session bean is “a logical extension of the client program that runs on the server” [ejbspec], p39.
A client can access a session bean by its remote and local interfaces, or its web service client view
(described in a WSDL document). A client can either be a remote client, sending requests over
various communication ports (RMI, web services, CORBA, see chapter 3.1.5.) or a local client in
the same server (e.g. another EJB).




                                                           12
Illustration 2: A client performs calls on the CartBean session bean over the
Cart interface. The CartBean is located in the container. [ejbspec], 46
                                                                              JSlave - Session Beans"



1.1.2 Session Bean Life Cycles

As mentioned in chapter II.2 there are two types of session beans, namely stateless and stateful
session beans.
The difference between those two types is the conversational state. The conversational state “is
defined as the session bean instance’s field values, its associated interceptors and their instance field
values” [ejbspec], p62.
Stateless session beans do not have a conversational state. Although a stateless session bean can
have attributes, the values stored in those attributes in a method call may be lost after the call is
finished. Because stateless session bean instances exists independently from a specific client, their
life cycle is controlled by the container. It is up to the container how many bean instances he holds.
“A container only needs to retain the number of instances required to service the current client load”
[ejbspec], p83. Thus he can increase the number of instances if there is a high number of client
requests and decrease the number of instances during periods of low traffic.
Stateful session beans have a conversational state and are bound to one client session. Their life
cycle is controlled by their corresponding client session. A stateful bean instance is created upon a
client request. It is destroyed when it is released by the client. Stateful beans can store information
in their fields that must be available during their whole life span. The container must be able to
passivate stateful bean instances. This means he has to serialize all serializable fields of a stateful
bean instance to an external memory (e.g. a database or a file) and remove the bean instance from
its own memory. If there is a call on a passivated bean instance the container has to reconstruct the
bean instance from this external resource. This feature is important for scalability purposes. If there
is a high amount of client requests on the container he must be able to clear his memory from bean
instances.



As a consequence of the life cycle of stateful session beans, stateful session bean instances can have
3 different states:

    ●   Does not exist

    ●   Ready




                                                   13
                                                                             JSlave - Session Beans"



       Actually, the EJB specification distinguishes between two different ready states. The reason
       therefore is another state that is used for transaction support.

   ●   Passive

Since a stateless bean instance does not have a conversational state it only has two states:

   ●   Does not exist

   ●   Ready

When a bean instance changes its state callback listeners can be invoked. This enables Bean
Providers to perform actions when the state changes. E.g. a Bean Provider may want to initialize
several classes after a bean instance is created or write information to a database when an stateful
bean instance is passivated or destroyed.

The following annotations are defined for marking callback listener methods in a session bean:

        Annotation                          Function                           Attached to
@PostContruct                 method is invoked directly after Method
                              construction of the bean instance
@PreDestroy                   method is invoked directly before Method
                              destruction of the bean instance
@PrePassivate                 method is invoked directly before Method
                              passivation of the bean instance
@PostActivate                 method is invoked directly after Method
                              activation of the bean instance


The life cycles of stateless and stateful session beans including their states and invocation of
callback methods are described in the following diagrams:




                                                  14
                                                                                         JSlave - Session Beans"



Stateful Session Beans




             Illustration 3: Life cycle of a stateful session bean[Sun02], p642
Stateless Session Beans




                         Illustration 4: Life cycle of a stateful session bean[Sun02],
                         p642



Stateful beans are similar to stateless beans with two exceptions:

   ●   Stateful bean instances are connected to only one client (internally or externally) during
       their lifetime and are destroyed when the connection is getting closed, while stateless bean
       instances can be stored in a stateless bean pool and serve business method calls from
       different connections.

   ●   Stateful bean instances can be passivated and activated during their lifetime by the container.




                                                        15
                                                                               JSlave - Session Beans"



Besides these differences their are some more differences mentioned in the EJB specification (e.g.
SessionSynchronization support), that have not been subject within JSlave due to the missing
transaction support.


1.2 Deployment


1.2.1 JEE application file formats

An implementation of a JEE application container must have simple and sufficient interfaces for the
deployment of an JEE application. First of all there have to be standardized file formats for JEE
applications.

The most comprehensive format is the Enterprise Application (.ear) file format. An EAR file is a
standardized Java archive file (.jar) with special information for JEE servers. According to [Sun02],
p53 a EAR file “contains Java EE modules and deployment descriptors. A deployment descriptor is
an XML document with an .xml extension that describes the deployment settings of an application,
a module, or a component”.
There are different types of deployment descriptors. The first and most important one is the Java EE
deployment descriptor, which is normally named application.xml. It “can be used to
configure deployment settings on any Java EE-compliant implementation” [Sun02], p53. Second
there are runtime deployment descriptors that can be used to configure implementation specific
deployment information. Because the runtime deployment descriptors contain information that
depend on the corresponding JEE server implementation they are not subject to this document. All
deployment descriptors must be in the META-INF directory of the EAR file.


The following modules can be included in a EAR file:
   ●   Web modules
       Contain classes and dynamic html pages for the web presentation layer in the JEE web
       container (servlets, jsp pages, etc.). Packaged in a .war file.
   ●   Application Client modules
       Contain all class files for the client application. Packaged in a .jar File.




                                                   16
                                                                                 JSlave - Deployment"



   ●   Resource Adapter modules
       Contain all class files, documentation and libraries for accessing external resources (e.g.
       other enterprise information systems). Packaged in a .rar file.
   ●   EJB modules
       Contain all EJB class files. Normally packaged in a .jar File but may also be packaged in a
       .ejb File.


According to [Sun02], p640 EJB modules contain the following elements:
   ●   Business interfaces
       Local and remote interfaces of an EJB.
   ●   EJB classes
       Bean classes that contain the business logic and implement the business interfaces.
   ●   Helper classes
       All classes needed by the bean classes (e.g interceptors, exception classes, utilities, etc.)
A single EJB module is also called an EJB-JAR file. Same as an EAR file, an EJB-JAR files can
have a JEE deployment descriptor for special deployment information (see III.1.3) and an
implementation specific runtime deployment descriptor. An EJB-JAR can contain one or more
EJBs. It is also possible to deploy an EJB-JAR directly to a JEE server, it does not have to be
assembled to a EAR file.


The following diagrams show the structure of EAR and EJB-JAR files:




                                                  17
                                                                            JSlave - Deployment"



Enterprise Archive File (EAR)




              Illustration 5: Structure of an EAR file([Sun02], p53)


EJB-archive file (EJB-JAR)




                 Illustration 6: Structure of an EJB-JAR, ([Sun02], p641)




                                                     18
                                                                                 JSlave - Deployment"



1.2.2 Deployment Process

Once the JEE application is packaged into the EAR or EJB-JAR file format by the Application
Assembler or Bean Provider, it has to be deployed into a JEE application container. Thus the
container must provide interfaces for deployment.

There are different possible ways for deploying applications. One possibility is to provide a web
interface that uploads an EAR or EJB-JAR file using an upload form. This method has the
advantage that it is mostly accessible from anywhere. On the other hand it is very hard with those
interfaces to create scripts or programs that automate the deployment process.

Another possibility for a deployment interface is to provide a deployment directory. For deployment
the JEE application has to be copied into the deployment directory and for undeployment it has to
be removed from this directory. This process can be easily automated (e.g. by makefiles or ANT
scripts). However this method requires that the deployment directory is permanently monitored.

Deployment directories are also the preferred way of deployment of existing application containers
(JBoss, GlassFish).

Once an application is submitted to the application container via its deployment interfaces it has to
be configured for the target operational environment. The following steps have to be done
([ejbspec], 2.2.3):

    ●   All additional classes needed by the application container must be generated.

    ●   All external dependencies have to be resolved. It must be ensured that all those
        dependencies are present before the first request can be made. (see Dependency Injection,
        chapter III.1.7)

    ●   Installing security configuration for all EJBs.

    ●   The remote interfaces, local interfaces and web service client views (WSDL) of all EJBs
        have to be registered in the naming services (RMI registry, UDDI, etc.).

Once the deployment is finished the installation of a JEE application is complete. From now on
requests on the EJBs contained in the JEE application can be performed.




                                                   19
                                                                        JSlave - Meta data processing"



1.3 Meta data processing

There are different ways of configuring EJBs in a JEE application. The first way is to define them
in an external deployment descriptor. This descriptor must be located in the META-INF directory of
the EJB-JAR file. This chapter only shows the most important meta data of session beans and the
most common ways of defining meta data. More detailed information about session bean meta data
can be found in the following chapters.

Since JEE 5.0 it is also possible to define the configuration for EJBs by using Java annotations. This
way is usually more convenient because all definitions can be made directly at the corresponding
elements in the source code. However, if the source code is not available all configurations can be
still made in the deployment descriptor.

The following table lists the annotations for defining session beans.

        Annotation                         Function                             Attached to
@Stateful                    defines a stateful session bean            Class
@Stateless                   defines a stateless session bean           Class
@Remote                      defines a remote business interface        Class, Interface
@Local                       defines a local business interface         Class, Interface


The @Stateful and @Stateless also have an additional name value. This value specifies
the binding name of the EJB in different naming services (JNDI, RMI, UDDI).

The @Remote and @Local can be both attached to bean classes and business interfaces. They
specify remote and local business interfaces. If attached to a class, one or more interface classes
have to be specified in the value property.

Additional annotations for defining callback listener methods have already been defined in III.1.1.2.

The following example describes the definition of a stateless session beans by either annotations or
using a deployment descriptor.

The following .java files are needed:




                                                  20
                                                                     JSlave - Meta data processing"



    ●   BusinessInterface.java: remote business interface

    ●   Bean.java: bean class implementing the business interface

    ●   ejb-jar.xml: optional deployment descriptor


@Remote
public interface BusinessInterface {
        public String businessMethod(String param1);
}


code 1: BusinessInterface.java



package basic.bean;

@Stateless(name="BasicBean")
public class Bean implements BusinessInterface {

        public String businessMethod(String param1) {
               // This method should be executed serverside...
               System.out.println("Business Method executing. param1 is \"" + param1 + "\"");

                 // ... while the return value should be sent back to the client.
                 return "Business Method executed. param1 was \"" + param1 + "\"";
        }
}

code 2: Bean.java

This bean is accessible through its remote interface BusinessInterface. It is bound to the
name BasicBean.

If no annotations would be used, the same configuration could be set with the following deployment
descriptor:

 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
 "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd">
 <ejb-jar>
        <enterprise-beans>
                <session>
                       <ejb-name>BasicBean</ejb-name>
                       <session-type>Stateless</session-type>
                       <ejb-class>basic.bean.Bean</ejb-class>
                       <remote>basic.bean.BusinessInterface</remote>
                </session>
        </enterprise-beans>
 </ejb-jar>

 code 3: ejb-jar.xml




                                                  21
                                                                        JSlave - Meta data processing"



Because almost all information in the deployment descriptor can also be defined by annotations it is
not necessary for JSlave to process all information of the deployment descriptor. Deployment
descriptors should only be read when there is information that cannot be described with annotations.




1.4 Interceptors

“Interceptors are used to interpose on business method invocations and life cycle events that occur
on an enterprise bean instance.”([ejbspec], p301)
      Terminology warning: The EJB specification does use the term “interceptor” for both life
      cycle callback methods and the actual interceptors. In the JSlave code emphasis has been put
      on to not mix these two technologies up.

Interceptor methods can be defined in a additional interceptor class or in the bean class itself.
Interceptor classes are defined by annotations in the bean class. The following annotations are
defined for configuring interceptors:
Annotation                 Function                                   Attached to
@Interceptors              defines Interceptor classes in bean Class
                           class
@AroundInvoke              defines interceptor method                 Method
@PostConstruct             method is invoked directly after Method
                           construction    of    the    interceptor
                           instance
@PreDestroy                method is invoked directly after Method
                           destruction of the interceptor instance
@PrePassivate              method is invoked directly after Method
                           passivation of the interceptor instance
@PostActivate              method is invoked directly after Method
                           activation of the interceptor instance




                                                  22
                                                                               JSlave - Interceptors"



Interceptor class instances are directly attached to a bean instance. Thus they have the same life
cycle. They are created when their corresponding bean instance is created, and destroyed when the
bean instance is destroyed. Interceptor instances of stateful beans are also activated and passivated.
Consequently interceptor instances can have the same callback listeners as bean instances. They are
defined with the same annotations (@PostConstruct, @PreDestroy, etc.).
Interceptors may also have external resources that must be provided by the application container
directly after construction (before @PostConstruct method, if any).


The @AroundInvoke annotation defines an interceptor method for business methods of session
beans. Such an interceptor method can be defined in an interceptor class or the bean class itself.
However only one method in a class can be defined as a interceptor method. In case of a bean class
the interceptor method cannot be a business method. Interceptor methods can also be defined in
superclasses of the interceptor or bean class. Consequently there has to be an order on when each
interceptor method is invoked. [ejbspec], 12.3.1 defines rules for creating this order, the most
important rules are:
   ●   interceptor methods defined in interceptor classes are invoked before any interceptor method
       defined in the bean classes
   ●   if there is more than one interceptor class, the interceptor methods of those classes are
       invoked in the same order as the classes are specified in the @Interceptors annotation.
   ●   if an interceptor class has superclasses the interceptors in the superclasses are invoked first,
       starting with the most general superclass.
   ●   if the bean class has any interceptor methods defined in superclasses, those interceptor
       method are invoked before the interceptor method in the bean class, starting with the most
       general superclass


Interceptor methods have the following signature:

@AroundInvoke
Object <METHOD>(InvocationContext) throws Exception

code 4: Interceptor method([ejbspec], 303)


“The InvocationContext object provides meta data that enables interceptor methods to




                                                    23
                                                                               JSlave - Interceptors"



control the behavior of the invocation chain.”([ejbspec], 308).

public interface InvocationContext {
       public Object getTarget();
       public Method getMethod();
       public Object[] getParameters();
       public void setParameters(Object[] params);
       public java.util.Map<String, Object> getContextData();
       public Object proceed() throws Exception;
}
code 5: InvocationContext([ejbspec], 308)

Methods:
    ●   getTarget: returns the bean instance
    ●   getMethod: returns the intercepted method
    ●   getParameters: returns the parameters of the intercepted method
    ●   setParameters: modify the parameter of the intercepted method
    ●   getContextData: returns the context data of the InvocationContext. As the
        InvocationContext is passed to all interceptors of a business method, interceptor
        methods can use the context data to store information that can be retrieved by other
        interceptor methods.
    ●   proceed: the next interceptor method is in the invocation chain is called. If the interceptor
        method is the last one in the chain the intercepted business method is called.



1.5 Remote Connections

EJBs can be accessed from remote clients by their remote business interfaces, web service client
views and CORBA. Because web services are a modern and platform independent way of
distributing applications it is not necessary for JSlave to support CORBA. The technology for
accessing EJBs over its remote business interfaces is not specified by [ejbspec], so the container
provider has to choose an appropriate existing communication protocol (RMI, RPC, etc.) or to
develop a new one. For JSlave the Java RMI technology should be used. Java RMI is part of the
Java Platform Standard Edition and provides a standardized communication platform.




                                                  24
                                                                              JSlave - Remote Connections"



All communication technologies that are used in the application container must provide some sort
of naming service. These naming services have to provide methods for registering communication
endpoints (remote interfaces, web service client views) and for looking up these endpoints.


1.5.1 Remote Method Invocation(RMI)

There are various communication technologies that allow the invocation of methods on remote
hosts (e.g. Remote Procedure Call (RPC)). However those technologies do not fit well into the
object oriented programming model. “Java Remote Method Invocation (RMI) is a distributed object
model for the Java programming language that retains the semantics of the Java platform’s object
model” ([rmispec], preface).
The RMI programming model is very similar to the client view model of a session bean (see
III.1.1.1). A server contains several objects. Those objects are called remote objects because remote
clients can get access to their methods by remote interfaces.
In RMI all remote interfaces must extend java.rmi.Remote. All methods in this interface have
to be declared with the exception type java.rmi.RemoteException in their throws clause.

public interface Hello extends Remote{
       public String sayHello() throws RemoteException;
}

code 6: Hello.java: Remote interface




 public class HelloImpl implements Hello {

         public String sayHello() {
                System.out.println("sayHello called");

                  return "Hello World!";
         }
 }

 code 7: HelloImpl.java: Remote object that implements the remote interface



Java Objects must either extend UnicastRemoteObject or use the static export() method
of UnicastRemoteObject in order to be exported as a remote object. Remote interfaces can be
registered in the RMI registry.




                                                        25
                                                                                   JSlave - Remote Connections"




 public class HelloServer {


         public static void main(String[] args) {
                String host;
                int port;

                  //setting hostname and port of the RMI registry
                  //....

                  try {
                                                                    exportObject(hImpl, 0);
                           Hello hSkel = (Hello) UnicastRemoteObject.
                           System.out.println("Skeleton created");

                           Registry registry = LocateRegistry.getRegistry(host, port);
                                                                                         );
                           System.out.println("Retrieved registry by class LocateRegistry"

                           registry.bind("Hello", hSkel);
                           System.out.println("Skeleton bound on registry");

                  } catch (Exception e) {
                         e.printStackTrace();
                         System.exit(0);
                  }
         }
 }

 code 8: HelloServer.java: exporting an remote object and bind it to the name "Hello"

If a client wants to use a remote object he has to get access to the RMI registry first. Then looks up
the corresponding remote interface of the remote object from the registry. Once he received it he
can perform calls on the remote object with this interface.

public class HelloClient {

         public static void main(String[] args) {
                String host;
                int port;
                Hello helloProxy;

                 //setting hostname and port of the RMI registry
                 //....

                 try {
                          Registry registry = LocateRegistry.getRegistry(host,port);
                                                                                        );
                          System.out.println("Retrieved registry by class LocateRegistry"

                          helloProxy = (Hello) registry.lookup("Hello");
                          System.out.println("Retrieved proxy");

                        System.out.println(helloProxy.sayHello());
                 } catch (Exception e) {
                        e.printStackTrace();
                 }
         }
}

code 9: HelloClient.java: Getting an remote interface and performing calls on it




                                                         26
                                                                      JSlave - Remote Connections"



Like RPC, the RMI system works internally with stubs and skeletons. “A stub for a remote
object acts as a client’s local representative or proxy for the remote object” ([rmispec], p15). The
client's remote interface is implemented by this stub. The stub is responsible for performing the
actual call on the server, this includes marshaling of parameters, opening sockets, writing and
reading those sockets and unmarshaling the return value. When a client requests a remote interface
he has to load the stub's byte code from a specific location to his class path. The location of the
stub's byte code can be specified by the java.rmi.server.codebase JVM argument.
On the remote object's side the skeleton is responsible for handling incoming calls. “The skeleton is
responsible for dispatching the call to the actual remote object implementation.”([rmispec], p16).
The skeleton has to listen on sockets for incoming calls, accept calls, unmarshal parameters, invoke
the method call on the remote object, marshal the return value and write it to the socket.


The RMI registry must be wrapped by a JNDI context. The Java Naming and Directory Interface
(JNDI) defines several platform independent naming and directory functions like the binding an
object in a directory to a specific name and retrieving the object under this name. There is already a
Context              factory              for              the             RMI                registry:
com.sun.jndi.rmi.registry.RegistryContextFactory.


However the RMI system needs to be modified to suit the requirements of an application container.
Remote business interfaces of EJBs do not have to extend the java.rmi.Remote interface and
the    methods     in     the    remote     business     interfaces    don't    have     to    include
java.rmi.RemoteException in their throws clause. The RMI stubs and skeletons have to be
modified or wrapped to meet these requirements.



1.5.2 Web Services

According to [ejbspec], 3.2.4 clients can also access session beans by their web service client views.
The web service client view is described in a WSDL document. In case of a java client the JAX-WS
2.0 or JAX-RPC can be used on the client side. SOAP is used as the communication protocol




                                                 27
                                                                                  JSlave - Remote Connections"



between client and application server. Because web services do not support sessions only stateless
session beans can have a web service client view.

This diagram describes the client access to the web service client views of stateless session beans:




            Illustration 7: Web service client views of stateless session beans([ejbspec], p49)



Web service client views can be defined in stateless beans by annotations. [JSR181] defines how the
information contained in those annotations translates into a WSDL document. The most important
annotations for defining web services are listed in the following table:

        Annotation                                Function                                  Attached to
@WebService                      Marks a class that implements a web Class
                                 service
@WebMethod                       Marks a method as a web service Method
                                 operation
@OneWay                          Marks a WebMethod as a web Method                           with   @WebMethod
                                 service operation that has no return annotation
                                 value, non-blocking call




                                                         28
                                                                      JSlave - Remote Connections"



The @WebService and @WebMethod annotations have several properties that customize the
bean's WSDL document. The most important properties are listed in the table below:

@WebService:

             Property                                             Function
name                                 The name of the web service. Used as wsdl:portType in
                                     a WSDL document. If not specified the simple Java class
                                     name is used as a default.
targetNamespace                      XML namespace
serviceName                          Service name of the web service. Used as wsdl:service
                                     in a WSDL document. If not specified the simple Java class
                                     name + Service is used as a default.
wsdlLocation                         Location of a predefined WSDL document.
endpointInterface                    Name of an optional interface. This interface can define the
                                     web service contract interface independently from the actual
                                     service implementation.


@WebMethod

             Property                                             Function
operationName                        Used as wsdl:operationName in a wsdl document
Action                               Value of the SOAPAction header


Web services can be published using the javax.xml.ws.Endpoint class, contained in the
JAX-WS library. From Java 6.0 on, this library will be part of Java SE.


1.6 Naming / Local Connections

EJBs can have dependencies on external resources and objects in their environment. “The key issue
is how enterprise beans can locate external information without prior knowledge of how the
external information is named and organized in the target operational environment.” ([ejbspec],



                                                29
                                                                          JSlave - Naming / Local Connections"



p401).
“The enterprise bean’s environment is a mechanism that allows customization of the enterprise
bean’s business logic during deployment or assembly” ([ejbspec], p403).
This feature is enabled by providing appropriate JNDI contexts and dependency injection.
Dependency injection is discussed in III.1.7.


Typical objects in the environment that are often needed by beans are:
     ●    SessionContext1
     ●    Timer Service
     ●    Other EJBs
     ●    Simple environment entries2
All dependencies have to be declared by java annotations or in the deployment descriptor. It must
be ensured by the application container that all dependencies are available for use by EJBs before
the first business method call.


The application container has to implement the bean's environment and provide it as a JNDI naming
context. One way for the bean provider to get access to this naming context by the lookup method
of       its   SessionContext.              Another        way       is      to   create      an     instance      of
javax.naming.InitialContext in the session bean and lookup the environment naming
context via this InitialContext under java:comp/env.


The        resources     EJBContext             and      TimerService              can      be      found       under
java:com/EJBContext and java:comp/TimerService.


It is also possible to look up other EJBs in the bean's environment. This enables local calls on EJBs.
A session bean that is called locally can be accessed through its local business interface. However,
if the bean provider wants to use the local interface he has to be aware that all method parameters of
1The SessionContext gives the session bean instance access to the instance’s context maintained by the
container([ejbspec], 66)
2 Simple environment entries are configuration parameters. They can only be one of the following data types:
     Boolean, Byte, Short, Integer, Long, Float, Double, Character, String




                                                         30
                                                                      JSlave - Naming / Local Connections"



the local interface are passed by reference. References to other EJBs should be stored in the
java:comp/env/ejb, which is a subcontext of the bean's environment context.
The following example shows the lookup of an external EJB:
@EJB(name=”ejb/Account”, beanInterface=AccountLocal.class)
@Stateless
public class AccountingServiceBean implements AccountingService {
       public void getAccount() {
               Context initCtx = new InitialContext();

                 AccountLocal result = (AccountLocal)initCtx.lookup( "java:comp/env/ejb/Account");
                 //...
        }
}

code 10: Getting a local EJB reference




1.7 Dependency Injection

As already mentioned dependencies can also be automatically injected by the application container.
Therefore they have to be marked by the corresponding annotations. The following list contains the
most important annotations for dependency injection:




            Annotation                              Function                         Attached to
@Resource                                The attribute or method is Attribute, Method
                                         injected by the container.
@EJB                                     The EJB reference is injected Attribute
                                         by the container.


If an attribute requests injection, the class name and method or attribute name is used in the
environment naming context. For example the field resource in the class basic.Bean would
correspond to the name java:comp/env/basic.Bean/resource. Also setter methods can
be injected by the container, they have to meet the naming requirements for Java beans setter
methods and start with set.




                                                        31
                                                                   JSlave - Dependency Injection"



The following resources are some of the values that can be marked for injection with the
@Resource annotation:

   ●    Simple environment entries

   ●    TimerService

   ●    EJBContext

   ●    SessionContext

The following example shows how a SessionContext field can be marked for injection, the
@EJB marks attributes that have to be injected with an EJB reference:


 @Resource
 private SessionContext sessionContext;

 code 11: SessionContext injection


1.8 Security

[ejbspec], 17 defines the security management in the EJB architecture. The EJB security
management enables bean providers and application assemblers to separate security policies from
business logic. One of the most important aims of the EJB security management is that business
methods should not contain any security related logic at all. Security policies should be defined in
meta data (annotations, deployment descriptor). Standardized meta data tags also ensure that the
bean provider can define security policies independently from the target operational environment.


The EJB security management is based on role based access control. “A role based access control
(RBAC) bases access control decisions on the functions a user is allowed to perform within an
organization” ([FKRbac],p3).
In order to perform a specific operation a user must belong to a security role that is allowed to
perform the action.




                                                32
                                                                                    JSlave - Security "



Example
The following example describes an example for a simple role based security management in an
eCommerce application. The first table lists all roles that are present in the whole system:


                        Role                                           Associated users
customer                                             All customers in the eCommerce system
sales                                                All sales personnel in the system
admin                                                All administrators in the system


The following operations can be performed in the system:
                    Operation                                            Description
placeOrder                                           Place an order in the system. An order consists
                                                     of one or more items.
cancelOrder                                          Cancel an order
changeOrder                                          Change an order
addItem                                              Add an item to the database. All items are
                                                     shown on the company's website.
removeItem                                           Remove an item from the database
changeItem                                           Change an item in the database
createUser                                           add a new user to the system
removeUser                                           remove a user from the system


The following table lists the operations that the different roles can access. If nothing is specified for
the corresponding operation/role the operation is not allowed for the role.
   operations / roles             customer                     sales                      admin
placeOrder                         allowed                   allowed                     allowed
cancelOrder                                                  allowed                     allowed
changeOrder                                                  allowed                     allowed
addItem                                                      allowed                     allowed
changeItem                                                   allowed                     allowed
removeItem                                                   allowed                     allowed
createUser                                                                               allowed



                                                   33
                                                                                    JSlave - Security "



removeUser                                                                             allowed


The following annotations can be used for defining roles in an EJB and to define which operations
they are allowed to perform:
Annotation                     Function                               Attached to
@DeclareRoles                  Defines all roles that are present in Class
                               an EJB
@RolesAllowed                  Defines the roles that are allowed Class, Method
                               to call a method.
@RunAs                         Defines the role an EJB has, when Class
                               the EJB itself      calls methods of
                               other EJBs
@PermitAll                     All roles are allowed to call the Class, Method
                               method
@DenyAll                       No role is allowed to call the Class, Method
                               method.


The @RolesAllowed, @RunAs and @DenyAll annotations can be both attached to classes and
methods. If they are attached to a class their function applies to all methods of the class. In this case
however role permission can be still overwritten for a specific method when there is a security
annotation attached to this method. E.g. the @DenyAll defines that access to all methods of a class
is denied for all roles, if a user wants to allow the group “admin” the access for a method, this
method must be annotated with @RolesAllowed(“admin”).
The roles can also be checked and processed in business methods by the methods
getCallerPrincipal and isCallerInRole of the EJBContext interface.




                                                   34
                                                           JSlave - Monitoring, Logging interfaces"



1.9 Monitoring, Logging interfaces

[ejbspec] does not specify how the monitoring, logging and administration interfaces of application
containers have to look like. Generally those interfaces should be implemented by using
standardized technologies.

Because the application container will be primarily used for demonstration purposes the monitoring
interfaces and logs should show significant information about the processes that run within a
container and the container's current state.

The most important processes that run within the container are:

   ●   business method calls

   ●   deployment of JEE applications

To show the current state of the application container the following attributes should be monitored:

   ●   active/passive bean instances, this includes their number and corresponding connections

   ●   active client connections

   ●   current bindings in the naming contexts

   ●   deployed applications and bean types

For logging purposes the Java logging interfaces (java.util.logging) can be used. The Java
logging         output         can         be         divided      into        various         levels
(FINE,FINER,FINEST,INFO,WARNING,SEVERE), thus providing the user a possibility to
filter the logging information. The user can adjust the settings (output format, level, etc.) of the
logger with an external logging.properties file.

For monitoring purposes the MBeans(managed beans) technology should be used. Managed beans
are components in a Java application that can be monitored. Java SE already provides a couple of
platform MBeans (so called MXBeans) that provide information of the current running JVM and
Java application. The following list shows some of these MXBeans:




                                                 35
                                                         JSlave - Monitoring, Logging interfaces"



   ●   RuntimeMXBean: management of the current runtime system

   ●   ClassLoaderMXBean: management of the class loading system (includes all loaded
       classes)

   ●   ThreadMXBean: management of the thread system (includes all running threads)

   ●   MemoryMXBean: management of the memory system (includes memory usage)

Additionally also new MBeans can be defined. Attributes of MBeans can be viewed and modified
by the standard Java beans getter and setter methods. All methods that should be available for
management purposes must be defined in a MBean interface. The interface's name must end with
MBean. E.g. if a class named BeanInstanceConfig should be used as a MBean its
management methods must be defined in an interface named BeanInstanceConfigMBean.

All MBeans are registered at the JVM's platform MBean server. This server is shared by all
applications running in the same JVM. Thus MBeans can be used for monitoring the application
server from a different application in the same JVM, e.g. by a web server using JSP.

The Java Development Kit (JDK) also provides a graphic console called jConsole for managing
MBeans. This console lists all available MBeans of specific application in a JVM. jConsole can also
be used for monitoring MBeans in a remote JVM.


2 Non-functional requirements

The application container will be used for demonstration and teaching purposes. Therefore the
stress for the code design lays more on writing easy and understandable code with a consistent
structure than on production quality code.

It is also no problem if free external software is used at technical hotspots that would become too
complex for this project.

Since the application server will also be used for an introduction to the EJB technology, the user
interfaces (deployment, JNDI) should not be too complex as primarily simple EJB examples will be




                                                36
                                                              JSlave - Non-functional requirements"



used. However the interfaces should be conform with standard Java technologies like RMI, JAX-
WS, JNDI, etc.




3 Further requirements according to specification

The most important difference between [ejbspec] and the actual requirements for the application
server is the lack of entity beans and message driven beans. Entity beans provide a model for all
persistent data in a system. This model is absolutely mandatory for every productive enterprise
application. Message driven beans provide asynchronous calls on business methods. These
asynchronous calls are important for batch jobs, e.g. a print job.

The application container does not provide support for any access to external resources as described
in [ejbspec], 16.7 + 16.8. These resources can be JDBC data sources, file systems, etc. Since there
is no access to any external data at all there is no need for transaction management ([ejbspec], 13).

For interoperability between different application container implementations the JEE Connector
API defines interfaces and methods for invocation of resources and EJBs located on a different
server runtime.

Another important aspect of the specification are chapters 7-11 [ejbspec]. In these chapters the
support for EJB 2.1 and EJB 1.1 applications is described. This is a very important aspect for
productive application container implementations, since the JEE specification desires a very high
compatibility with older version. These versions are not supported in this project.




                                                  37
                                                                                  JSlave - Implementation"




IV Implementation

1 Structure

1.1 Overall structure


1.1.1 Base Classes

The main class for JSlave is ApplicationServer, containing the main() method. Upon
initialization   this   class   creates   an   instance    of   the   actual     Container     class. The
ApplicationServer class also has an instance of the Configuration class. The
Configuration class stores all global configuration parameters. ApplicationServer is
implemented as a singleton.

The ApplicationServer class controls the startup and shutdown of the application. Its most
important methods are:

                        Method                                                 Description
public void startup()                                     Starts the application server and the actual
                                                          container instance.
public void shutDown()                                    Stops the application server and the container
                                                          instance.
public Container getContainer()                           Returns the current container instance.
public Configuration getConfiguration()                   Returns the current server configuration. The
                                                          configuration settings can be set by modifying
                                                          the {server}/server.properties.




                                                    38
                                                                            JSlave - Overall structure"



The Container class keeps the instances of all service classes. These service classes represent
independent components that represent the different services offered by JSlave. All service classes
implement the Service interface.

The Container provides the basic public functions for the deployment and business method
calls. However, the Container class mostly delegates the functions to the service classes.

The most important methods of the Container class are:

                    Method                                               Description
public void deploy(EnterpriseApplication
                                                  Deploys a new Application. The application can
application)
                                                  either be a complete EAR file or a EJB-JAR
                                                  module.
public void undeploy(EnterpriseApplication
                                                  Undeploys an EAR file or EJB-JAR module
application)
public void deployAll()
                                                  Deploys          all     applications     in     the
                                                  {server}/deploy directory. This function is
                                                  needed upon startup of the container.
public void undeployAll()                         Undeploys all applications that are currently
                                                  deployed in the container. This method is needed
                                                  when the container is shut down.
public Bean findBean(Class<?> beanClass)          Checks if a specific bean class is deployed in the
                                                  container. Returns the corresponding Bean
                                                  class, if yes.
public BeanInstance getBeanInstance(Bean bean,    Returns a bean instance for a specific client
Connection connection)
                                                  connection. This method is called when a client
                                                  submits a business method call. This method call
                                                  invokes the BeanInstanceManager service.
public void releaseBean(BeanInstance              Releases a bean instance from a specific
beanInstance)
                                                  connection. This method is called when a bean
                                                  instance is not needed anymore by a connection.
                                                  This       method          call      invokes     the




                                                 39
                                                                       JSlave - Overall structure"



                                                  BeanInstanceManager service.


The following UML Diagram shows the most important classes of JSlave:




Illustration 8: UML diagram base classes

The Bean class holds all information about a deployed EJB. This information includes all meta
data and information about the deployment environment of the bean's corresponding archive. The
Container class stores all Bean instances that are currently available in the container. A specific
Bean instance can be obtained by the findBean method.


1.1.2 Service Classes

As mentioned in the previous chapter the Container class controls the service classes. All
service classes implement the interface Service. Thus they have to implement the start() and




                                                40
                                                                           JSlave - Overall structure"



stop() methods. The start() method is intended for initializing the service. E.g. in this
method the service can initialize its data structures or start external services like the RMI registry.
The stop() method is intended for shutdown operations, e.g. closing of files, streams, garbage
collection, etc.

The Container itself is a service class. Its start() and stop() methods are invoked by the
ApplicationServer class.

The container manages the following services:

                   Service Class                                      Description
BeanInstanceManager                                 Manages the allocation and destruction of bean
                                                    instances. Manages the stateless bean pool.
BeanExecutionManager                                Invokes all method calls and status changes on a
                                                    specific bean instance.
SatefulBeanSerializer                               Serializes and deserializes a bean instance upon
                                                    activation and passivation.
UserManager                                         Performs the user authentication. Uses the
                                                    user.properties file in the {server} directory
                                                    as a user database.
DistributionManager                                 Responsible for registering remote and web
                                                    service client views at the corresponding naming
                                                    services(UDDI, etc.)
ConnectionManager                                   Manages local and remote connections.
ClientViewManager                                   Manages local and remote client views.
JNDINamingManager                                   Responsible for creation and management of a
                                                    bean's environment naming context.
AutoDeployer                                        Monitors the {server}/deploy and invokes
                                                    the container's deploy and undeploy methods
BeanFactory                                         Creates the Bean classes.
MBeanManager                                        Manages all MBeans available in JSlave.
                                                    Register new MBeans at the Platform MBean




                                                 41
                                                                     JSlave - Overall structure"



                                                          Server.



1.1.3 Basic Connection and Bean classes

The following UML diagram show the basic classes for bean instances and connections:




Illustration 9: UML diagram basic connection and bean classes



The abstract BeanInstance class represents exactly one instance of the EJB class. The actual
bean instance that executes the business logic is stored in the attribute beanImpl. A business
method call on the bean instance is invoked by Java reflection in the method



                                                       42
                                                                          JSlave - Overall structure"



doBusinessMethod(). There are two subclasses of the BeanInstance class, representing
stateful and stateless bean instances. These classes provide overwritten versions of the
doBusinessMethod(). The BeanInstance class also keeps a reference of the Bean class
(see chapter IV.1.1.1). If a BeanInstance is used by a client the corresponding connection is
stored in the connection field. If an instance is released from a specific connection this field is
set to null.

The abstract Connection class represents a connection to a specific client. This class stores
information about the actual connection. It also requests BeanInstances from the Container and
performs the actual business method calls (doBusinessMethod()) upon client requests. Like
the BeanInstance class the Connection class has sub classes for client connections to stateful
and stateless beans. They differ mostly in the way how bean instances are requested and released.

       Terminology Warning: This chapter will use the term “Bean” to refer to the Bean class that is
       implemented by the Bean Provider and the term “Bean Instance” to refer to an instance of
       this class.

       Please remember not to mix this up with the terms Bean and BeanInstance
       (monospaced) that refer to the JSlave classes and are part of its data model.


1.2 Project structure

The JSlave project is divided into two subprojects:

   ●    appserver: contains all sources for the actual JSlave project.

   ●    trmijndi: contains modified sources of the TRMI open source project, a JNDI port for
        TRMI and the authentication extension for the use with JSlave

The TRMI (Transparent RMI) project will be discussed in chapter IV.5.1.2.

The appserver project can be divided in two top level packages:

   ●    de.fhr.ejb3container: all JSlave specific sources




                                                  43
                                                                         JSlave - Project structure"



   ●   de.fhr.util: global utility library, contains File handling functions, Jar utilities, etc.

The de.fhr.ejb3container packages has the following subpackages:

   ●   clientview: definitions and management for client views

   ●   connection: definitions and management for connections

   ●   container: contains the Container class and the Service interface

   ●   distribution: contains all sources for registering client views at the naming services
       (RMI registry, UDDI)

   ●   ejbcontext: EJBContext and SessionContext implementations

   ●   instance: definitions and management of bean instances

   ●   jmx: MBean classes and interfaces

   ●   model: definitions for beans, applications, meta data

   ●   naming: implementation of the bean environment naming context

   ●   proxy: definitions and generators for proxy classes

   ●   security: definitions and management of security classes

   ●   threading: multithreading controllers

   ●   timerservice: definition and management of timing services




1.3 Server folder structure

The JSlave project has the following directory structure:

   ●   bin/ : JSlave binaries




                                                 44
                                                                  JSlave - Server folder structure"



   ●    lib/ : libraries needed by JSlave

   ●    {server}/ : contains the actual server runtime configuration

   ●    {server}/lib/ : libs needed by JEE client applications and the deployed beans at
        runtime

   ●    {server}/deploy/ : deployment directory

   ●    {server}/work/ : work copies of JEE applications and generated sources

   ●    {server}/log/ : contains all server logs

This directory structure can be modified by the {server}/server.properties.

       The reason for putting {server} into curled brackets is, that JSlave allows to configure the
       used path by using the command line.




                                                45
                                                                       JSlave - Deployment Process"




2 Deployment Process

By storing an enterprise bean archive (i.e. an .EAR archive or an EJB-Jar) into the
{server}/deploy folder, the Deployer can trigger the Deployment Process (Hot Deployment).
The Deployment Process contains of the following mechanisms:

   1. Creation of a subfolder of the {server}/work folder

      This subfolder will be used as a temporary work folder for JSlave, where the classes and
      meta data will be loaded from. If the enterprise bean archive is an .EAR archive, the
      contents of the archive will be unpacked to this subfolder; an EJB-Jar will be copied directly
      to       that      subfolder.      For         example,      the        contents         of     a
      {server}/deploy/beanarchive.ear will be unpacked into the directory
      {server}/work/beanarchive.ear,                                      while                       a
      {server}/deploy/beanarchive.ejb3                     will   be     copied   to     the   directory
      {server}/work/beanarchive.ejb3/beanarchive.ejb3.

      The corresponding subfolder in turn includes a folder generated that is used for the
      creation and compilation of proxy classes.

   2. Creation of data structures to represent the meta data and the beans

      In this step JSlave creates data structures to hold and process the meta data from the
      deployment descriptors (i.e. the meta-inf/application.xml of a .EAR archive and
      the meta-inf/ejb-jar.xml of the EJB-Jars) and the Java annotations, as well as data
      structures that represent the bean within the container.

            A more detailed analysis of the meta data processing follows in IV.2.2.

   3. Creation of the Beans' Environment Contexts

      Like specified in [ejbspec], 16 every bean has its own private so-called Bean Environment,
      that is used to fulfill the dependencies on external resources and other beans. The Bean




                                                46
                                                                      JSlave - Deployment Process"



       Environment is accessible for the bean by either using Dependency Injection or by lookup
       of the values from the JNDI context java:comp.

             A more detailed analysis of the Bean Environment Context follows in IV.2.3.

   4. Creation of the Proxy class

       For exporting a web service client view a proxy class with web service annotations must be
       generated. This proxy class is intended for receiving all incoming SOAP messages and
       redirecting them to the business method calls to a Connection object.

             This topic will be discussed in detail in IV.2.4

   5. Publishing of the bean's functionality over the distribution networks

       At that point the bean is bound to its specified name in one or more naming services. In this
       version, JSlave will distribute a bean via RMI and via SOAP.

             This topic will be discussed in detail in IV.5.

By deleting a file from or changing a file within the {server}/deploy directory, or by shutting
down JSlave the undeployment process can be triggered. This will

   1. unbind the affected beans from the distribution networks

   2. close open external and internal connections to the affected beans (can force the closure of
       further connections, for instance if a bean is having a connection to another bean that is
       subject of the closure)

   3. remove stateless bean instances from the stateless bean pool

   4. dereference all data structures to the affected beans and meta data sources (and in this way
       enable them to be garbage collected)

             In the current version of JSlave the implementation suffers from a reference from the
             RMI subsystem to a bean's client view. This reference prevents the garbage collection
             for approximately 15 minutes to clean up the memory like desired.




                                                  47
                                                                       JSlave - Deployment Process"



    5. remove the subfolder under {server}/work


2.1 ClassLoader Delegation Hierarchy

To load the bean classes at runtime JSlave uses the Java ClassLoader mechanism, which allows to
load code during runtime and to execute it by using the Java Reflection API, even though it might
be code that has not been declared at compile time. The Java ClassLoader mechanism contains
methods that support the delegation of loading requests to other class loaders, so that classes that
cannot be found by one ClassLoader are delegated to another ClassLoader, which might be able to
fulfill the loading request.

It is important to mention, that classes loaded from different ClassLoaders are not inter-operable
(besides the use of the Reflection API). Not being inter-operable in this context means, that a class
A loaded from one ClassLoader is not the same as the same class A from another ClassLoader. Even
the instanceof operator and typecasts will not work like desired. The only way to get access to
the methods of classes loaded from another ClassLoader is by using the Reflection API.
Nonetheless, two distinct ClassLoaders can still delegate to one common ClassLoader and thus
allowing an interoperability. This is usually the case for all Java bootstrap classes like returned from
ClassLoader.getSystemClassLoader().

      An advantageous side effect of these properties is that bean classes from different bean
      archives are isolated from each other quite well (like required by the [ejbspec] 17.6.9 ), as
      they are loaded by different ClassLoaders. Anyhow, this isolation cannot replace the
      postulated complete security concept, as the use of the Reflection API would still allow a
      bean to interfere with the container's code and/or other enterprise applications.




                                                  48
                                                                JSlave - ClassLoader Delegation Hierarchy"




Illustration 10: In the current version of JSlave each enterprise bean archive will have a superordinate ClassLoader
for the whole archive, and one more more subordinate ClassLoaders for each EJB-Jar.



A common superordinate EnterpriseApplicationClassLoader is necessary for the
following reasons:

    1. The meta data from the meta-inf/application.xml of a .EAR archive can refer to
        any class of the contained EJB-Jars and therefore must be reachable from all subordinate
        ClassLoaders.

               As JSlave in its current version ignores the meta-inf/application.xml this is
               just a theoretical argument.

    2. Like specified in [ejbspec], 21.2 the container is responsible to provide implementations for
        various JEE APIs in the beans' runtime environments. By using a superordinate ClassLoader
        for these libraries the memory consumption can be reduced radically, as otherwise for every
        EJB-Jar the contents of the {server}/lib directory would be loaded separately.

The classes of JSlave itself are loaded by the SystemClassLoader, whose class path contains
the files from bin and lib besides the bootstrap-classpath.




                                                         49
                                                                   JSlave - Meta Data Processing"



2.2 Meta Data Processing

The meta data, that can be used to describe a bean and its environment according to the EJB
specification, can be originated from different sources:

   ●   the meta data, that can be attached to the bean code itself by using Java Annotations

   ●   the meta data, that can be stored within the deployment descriptor of an EJB-Jar archive in
       meta-inf/ejb-jar.xml

   ●   the meta data, that can be stored within the deployment descriptor of a .EAR archive in
       meta-inf/application.xml

   ●   from vendor-specific deployment-tools that are not specified by the EJB specification

The information from these different sources have to be merged by the rules defined in the EJB
specification. Generally speaking the lower items in the list above can override the upper items; but
that may not be the case for certain information.

JSlave in its current version uses the meta data only to a very limited extend, as just the annotated
meta data will be processed at all (and not even completely). The meta data from ejb-jar.xml
and from application.xml are ignored. Nevertheless, the meta data processing subsystem is
prepared to support the different meta data information sources like shown in this UML diagram:




                                                    50
                                                                      JSlave - Meta Data Processing"




Illustration 11: UML diagram meta data



The current versions of ApplicationMetaData (covering data from application.xml)
and    DescriptorMetaData                (covering   data   from   ejb-jar.xml)    are   stubs,   and
CompositeMetaData, which is responsible for returning the meta data that result from the
annotations and the deployment descriptor by using the rules defined in the EJB specification,
simply returns the meta data from the annotations.




                                                     51
                                                                     JSlave - Bean Environment"



2.3 Bean Environment

The Bean Environment is accessible for the Bean by using either Dependency Injection or a
programmatic JNDI lookup. According to the [ejbspec],16.2.1 every injection and every lookup
will create a new instance of the requested object.

JSlave creates an implementation of the JNDI Context interface for each bean during the
deployment process. This Context is bound to the java:comp from within the bean code (see
V.1) and also used to lookup the values that are to be set by using the Dependency Injection. This
means that every Bean has its own private java:comp interface, that must be multiplexed within
the container based on from which Bean it was looked up.

As every lookup must return a new instance of the requested object, the JNDI support for factories
is used (based on ObjectFactory implementations). By using this technique, no actual object is
bound to the Context, but          Reference objects. These objects are meant to hold enough
information for a ObjectFactory implementation to create a new instance of the requested
object on every lookup.

Although [ejbspec], 16 defines 14 different types of environment entries, JSlave in the current
version only supports the following types:

   ●   Simple Environment Entries ([ejbspec] 16.4)

       Simple Environment Entries can be one of the following Java types: String, Character,
       Integer, Boolean, Double, Byte, Short, Long, and Float.

             As the values of Simple Environment Entries can only be set by using the Deployment
             Descriptor but the Deployment Descriptor is ignored by the current implementation, it
             is not possible to test this behavior.

   ●   EJB References ([ejbspec], 16.5)

       EJB References are references to other Session Beans and actually the only possible way to
       get a local client view, because the distribution networks like RMI and WebService only
       export remote interfaces.



                                                      52
                                                                        JSlave - Bean Environment"



   ●   TimerService References ([ejbspec] 16.14)

       The EJB specification requires an EJB container to provide an implementation of the
       TimerService interface under java:comp/TimerService.

             Although the JSlave will provide a TimerService implementation, the implemented
             methods are only method stubs and will not work properly. It could easily be replaced
             by   a   real     enterprise   job   scheduling   system   like   the   Quartz   project
             (http://www.opensymphony.com/quartz).

   ●   EJBContext References ([ejbspec], 16.15)

       By    providing    an     EJBContext        or   SessionContext           implementation    at
       java:comp/EJBContext, a bean can interact with the container. The special attribute of
       an EJBContext is that some methods can give information related to a bean instance
       rather than a bean (e.g. EJBContext.getCallerPrincipal()). Therefore another
       multiplexing mechanism is needed (like described in V.1).


2.4 Dynamic Proxy Creation

If an EJB has a @WebService annotation a web service client view must be provided. For this
purpose a proxy class must be generated. This proxy class must include all methods of the bean
class that are annotated with @WebMethod.

A generated proxy class extends the base class ProxyBase. This class keeps an instance of the
InvocationHandler class. The InvocationHandler class is responsible for submitting
business method calls to the corresponding Connection object. The generated proxy class
redirects all incoming requests to the doMethod() method of the ProxyBase class. This
methods redirects all calls to the InvocationHandler object. The generated proxy class's name
is always composed according to this rule: [bean's class name]Proxy. The generated proxy
class must contain the same annotations as the original bean class.

The following class is an example for a generated proxy class:




                                                  53
                                                                     JSlave - Dynamic Proxy Creation"




@javax.ejb.Stateless(name="AppServerTestBean")
public class BeanProxy extends de.fhr.ejb3container.proxy.ProxyBase
 implements
basic.bean.BusinessInterface
{
       public BeanProxy ( java.lang.reflect.InvocationHandler invocationHandler ,       Class<?>[]
implementedClasses )
       {
               super(invocationHandler, implementedClasses);
       }
       public java.lang.String businessMethod ( java.lang.String param0 )
       {
               Class<?>[] paramTypes = new Class<?>[1];
               paramTypes[0] = param0.getClass();

                 Object[] params = new Object[1];
                 params[0] = param0;
                 return (java.lang.String) doMethod("businessMethod",paramTypes,params);
         }

}


code 12: generated proxy class




The proxy class generation and compilation is controlled by the EndpointGenerator class.
The methods for this purpose are:

                       Method                                            Description
public   EndpointClass    generateEndpointClass(Bean
                                                       This method generates a proxy class out of a
bean)
                                                       given Bean class. The output of this method is a
                                                       EndpointClass. This class represents a
                                                       generated proxy class.
public Class<ProxyBase>                                This method compiles a generated proxy class.
compileEndpoint(EndpointClass endpointClass)
                                                       Class name and path for compilation are set in
                                                       the EndpointClass object. The output of this
                                                       method is the Class object of the generated
                                                       proxy class


The generated proxy class is represented by an EndpointClass object. Upon initialization of the
EndpointClass the proxy class is generated. The following steps are necessary for the
generation:




                                                  54
                                                              JSlave - Dynamic Proxy Creation"



   1. The ClassHead information must be read. This information includes @WebService
       annotations, @SOAPBinding annotations, implemented interfaces, extended subclasses.

   2. All methods annotated with the @WebMethod annotation must be read. These methods are
       stored in an instance of the MethodData class.

   3. An object of the ClassWriter class must be created. This class performs all file writing
       operations.

   4. The ClassWriter object must create the class head upon the information contained in the
       ClassHead object.

   5. The ClassWriter object must create the methods upon the information contained in the
       MethodData object.



The following UML diagram shows all classes that are involved in the proxy generation process:




                                               55
                                                     JSlave - Dynamic Proxy Creation"




Illustration 12: UML diagram Proxy generation




                                                56
                                                                JSlave - Connection management"




3 Connection management

A connection in this context is the data structure that JSlave creates to model an incoming
connection from one of the distribution networks or from the java:comp JNDI context. It stores
parameters of the connection like the caller's Principal or the host, from where this connection
has been established.

Connection instances are created and stored by the ConnectionManager, which provides
factory methods and other methods to maintain the active connections. Generally, it has to be
distinguished between external and internal connections, whereas external connections refer to
connections made from other JVMs and internal connections refer to connections established from
the same JVM as the container runs in.

Depending on from which distribution system the connection is made, the process looks like the
following:

   ●   RMI Connection

       Whenever a lookup of a bean is being performed on the RMI registry the registry will call
       the ConnectionManager.createClientConnection() method to let the
       ConnectionManager create a new Connection. The RMI registry will further create
       a client view proxy and send it back to the caller. When the proxy is going to be deleted by
       the Distributed Garbage Collection, it will close the connection again by calling
       ConnectionManager.closeConnection().

             More details on how the RMI distribution system works can be found in IV.5.1.

   ●   Web Service Connection

       A call of a web method by using a web service endpoint results in a creation of a new
       connection every time. After the execution of the called web method the connection is
       immediately closed again. The instant creation and closure of a Connection is due to the
       fact, that every call of a web method might be called by using different user credentials, and
       that therefore a new Connection must be used.




                                                57
                                                                      JSlave - Connection management"



                 More details on how the web service distribution system works can be found in IV.5.2.

      ●    Internal Connection

           By using Dependency Injection or JNDI lookup a bean instance is able to create an internal
           connection to another bean instance. Therefore on each lookup operation a new
           Connection and a client view proxy are created and returned (similar to the RMI case).
           When the proxy is not longer referenced from the bean instance, the Garbage Collection will
           remove the proxy and call its finalize() method that in turn closes the connection.

           Unlike the connections established via RMI and web services the internal connections are
           the only ones the are allowed to publish the local interfaces of a session bean (in addition to
           the remote interfaces).

If the bean that the connection refers to is a stateful bean, a StatefulConnection is created.
The StatefulConnection calls the BeanInstanceManager.allocBeanInstance()
to create a new StatefulBeanInstance on the first time a business method is called (lazy
initialization). When the StatefulConnection is closed, the bean instance is released again.
BeanInstanceManager is responsible for creating and destroying the bean instances and is to
be described in detail in IV.4.1.

If the referred bean is a stateless bean a StatelessConnection is created. Unlike the
StatefulConnection it allocates and releases a bean instance on every business method call
and       thus   moves    the    responsibility   to   create   and   destroy   bean   instances   to   the
BeanInstanceManager.

          For reading the source code it might be helpful to note that we used the term Client
          Connection for methods that deal with connections from external hosts, while a Connection is
          the more general term and refers to connections that might either be established internally or
          externally.




                                                       58
                                                                                 JSlave - Client Views"



3.1 Client Views

Client views are the previously mentioned proxies that are returned from lookup calls and described
in [ejbspec], 3. The main reason for never returning the actual bean instance from a lookup is the
need to call the container's functionality before and after the actual business logic (containing of
Bean Instance Pooling, Security, Life cycle Management, Interceptor Invocation, Dependency
Injection, a.s.o.) is invoked.

JSlave uses java.lang.reflect.Proxy instances for the use with RMI and internal
connections and the manually created proxies for web services (see IV.2.4). Unfortunately it was
not possible to unify both types because of the different requirements of web services and RMI
distribution systems. Nevertheless both types delegate a business method call to an
InvocationHandler, that in turn will use a Connection instance to execute the actual
business logic.

The Client Views for RMI and internal connections are created by factory methods of the
ClientViewManager                class.   Every        lookup   will       result     in     a     new
java.lang.reflect.Proxy instance; the associated InvocationHandler will be
parametrized with the Connection instance it is referring to. When the proxy is removed by the
(Distributed) Garbage Collection it closes the Connection within the finalize() method.

In comparison to that the client view for a web service exists only once per Bean. The
WebserviceInvocationHandler creates a new connection for every incoming business
method call and closes it immediately after invoking the business logic.


3.2 Connection Tree Structure

The Connection instances are organized in a tree structure to model dependencies between
different connections. Connections from external hosts (via RMI or web services) are therefore
always the roots of the connection hierarchy and stored in the ConnectionManager as so-called
Client Connections. Internal connections that have been established by Dependency Injection or
JNDI lookup are either directly or indirectly children of a Client Connection.




                                                  59
                                                                         JSlave - Connection Tree Structure"



Example
The stateful bean EJBInteractiveAdministration like defined in the Course
Administration       Sample       (see       VI.3.2)     is    dependent        from   the   stateless   bean
EJBProfessorAdministration:
public class EJBInteractiveAdministration implements InteractiveAdministration {
       @EJB(mappedName="EJBProfessorAdministration")
       private ProfessorAdministration administration;
}

code 13: EJBInteractiveAdministration.java


The lookup of an instance of the EJBInteractiveAdministration via RMI would result in
the following Connection hierarchy:




                          Illustration 13: Connections resulting from a RMI call of
                          EJBInteractiveAdministration




                                                         60
                                                                 JSlave - Connection Tree Structure"



The main purpose of modeling the connection tree structure – besides the advantages for logging
and monitoring – is the need to find connections that are dependent from a connection that will be
closed.   In   the   example     above,     the   closure   of    the   RMI    connection     to   the
EJBInteractiveAdministration instance must close the internal connection to
EJBProfessorAdministration as well.

     The connection tree structure should not be mixed up with the connection class hierarchy
     containing the classes Connection, SessionConnection, StatefulConnection
     and StatelessConnection.


3.3 EJBContext and SessionContext

The EJBContext interface (and the SessionContext interface, repectively) is the only way
for a bean instance to interact with the container; besides these interfaces the container has to be
transparent for both the bean instance and the clients. The bean can get access to the EJBContext
interface by either Dependency Injection or JNDI lookup of java:comp/EJBContext. The
SessionContext interface extends the EJBContext interface and is used in session beans.

After the EJBContext interface provides methods for getting connection-specific information
like the caller's principal, for every Connection instance an instance of EJBContext is created.
Since the CompContext class (implementing the java:comp JNDI context) is unique for each
Bean instance but the EJBContext is unique for each BeanInstance instance, a multiplexing
has to be performed. The multiplexing mechanism finds the requested EJBContext instance by
using the Thread.currentThread() and BeanExecutionManager.


4 Life Cycle of a Session Bean Instance

The majority of the container's functionality is performed by the class BeanInstance and its sub
classes, that represent an instance of a bean class in the container. The methods of
BeanInstance         are   not   intended    to   be   called    from   any   other   class   besides




                                                  61
                                                    JSlave - Life Cycle of a Session Bean Instance"



BeanInstanceManager, which is responsible for creation and removal, management,
threading, and stateless bean pooling.

A SessionBeanInstance can have one or more InterceptorInstance instances, that
represent a interceptor instance of a session bean and share its life cycle and bean environment.




Illustration 14: UML Diagram bean instances



The BeanInstance hierarchy introduces different functionalities:

    ●   BeanInstance




                                                 62
                                                     JSlave - Life Cycle of a Session Bean Instance"



       The BeanInstance class creates and destroys the actual instance of a bean class, calls
       potential life cycle callback listener (like postConstruct and preDestroy), invokes
       the dependency injection, and performs the security checks.

   ●   SessionBeanInstance

       SessionBeanInstance extends the BeanInstance functionality by the interceptor
       stack and its invocation.

   ●   StatelessBeanInstance

       StatelessBeanInstance extends the SessionBeanInstance by a method to call
       business methods.

   ●   StatefulBeanInstance

       StatefulBeanInstance                extends       the     SessionBeanInstance                by
       passivation/activation mechanisms and a method to call business methods (slightly different
       from StatelessBeanInstance).

During its lifetime a BeanInstance is always connected to an Connection object, as it can
only be created as the result of a new connection (internally or externally). Only the connection of a
StatelessBeanInstance changes with every business method call and can be null (if a
StatelessBeanInstance instance is in the stateless bean pool).

To implement the instance creation and destruction, BeanInstance defines the two methods
construct() and destroy() that are called by BeanInstanceManager whenever a new
instance is to be created or destroyed, respectively. The sequence of mechanisms in the
construct() method is:

   1. Creation of instances for all configured interceptors of a bean class and the bean class itself.

   2. Dependency Injection into the interceptor instances and the bean instance.

   3. Call of potential postConstruct() methods on the interceptor instances and the bean
       instance.



                                                 63
                                                        JSlave - Life Cycle of a Session Bean Instance"



The destroy() method first calls the preDestroy() methods of the bean instance and the
interceptor instances and then removes the reference to these instances.


4.1 BeanInstanceManager

Instead of calling methods of the BeanInstance classes directly, all uses of BeanInstance
methods are made from BeanInstanceManager. The most important ones are:

   ●      allocBeanInstance()

          creates a new BeanInstance instance and returns it. In case of a stateless bean a
          matching StatelessBeanInstance may be fetched from the stateless bean pool
          instead of creating a new instance.

   ●      doBusinessMethod()

          exists in two variants as there is a slight difference between the stateful and the stateless
          case.

   ●      releaseBeanInstance()

          after the work with a BeanInstance it has to be released using this function. A
          StatefulBeanInstance will be destroyed, while a StatelessBeanInstance
          might be stored in the stateless bean pool.

BeanInstanceManager               automatically    cares    for   creation   and   destruction   of   the
BeanInstance instances, provides management functions, and contains the stateless bean pool.
Furthermore, the execution of all BeanInstance methods is not executed in the caller's thread
but sent to the job queue of BeanExecutionManager to allow a better control of concurrent
access.

       BeanExecutionManager and the threading behavior will be described in IV.7.




                                                    64
                                                   JSlave - Bean and Interceptor Instance Creation"



4.2 Bean and Interceptor Instance Creation

BeanInstance provides the two methods construct() and destroy(), that are used from
BeanInstanceManager to create a new instance of the actual bean class and destroy it,
respectively. In case of StatefulBeanInstance the instance of the bean class can be
destroyed by using the passivate() method and will be reconstructed as a result of the
activate() method as well.

Interceptors share the life cycle of the session bean instances they are attached to, and can be
configured at method level, at class level, and at application archive level. Anyway, only one
instance of every used interceptor class is created per bean instance. Interceptor instances are
created and activated before the associated bean instance and destroyed and passivated after the
associated bean instance.

      The call of the aroundInvoke() method of the interceptor instances and the preparation
      of the interceptor stack will be discussed in IV.4.5.

Dependency Injection

The EJB specification requires the Container Provider to support Dependency Injection as a way to
set values for fields of bean and interceptor instances. The values can be defined by the Application
Assembler and the Deployer by using the descriptor files, or the container itself (e.g.
TimerService and EJBContext) and are stored in the Bean Environment.

Generally, the values can be injected in the instance variables itself or by using an appropriate setter
method, depending on the element the injection is targeting to. The injection must work not only on
public elements; protected and even private methods and fields can be target of an
injection as well. That is only possible as the Java Reflection API provides the method
setAccessible() for fields and methods and thus allows the access to even private
elements.

The class DependencyInjector provides this functionality. It is called from the
construct() method of BeanInstance for the bean instance itself and for all the




                                                  65
                                                  JSlave - Bean and Interceptor Instance Creation"



interceptors, and injects the values from the Bean Environment into the fields and methods, that are
designated for injection. The values are fetched from the java:comp context of a Bean; in case of
injection of other beans (e.g. by using @EJB) this will cause the creation of new internal
connections and the injection of a corresponding client view proxy.

      StatelessBeanInstance starts a special variant of the dependency injection before
      each call to a business method and injects the value for java:comp/EJBContext again.
      This is due to the fact, that each call usually will be made from a different Connection and
      therefore the java:comp/EJBContext can be different.


4.3 Life Cycle Callbacks

[ejbspec], 4.3.4 allows the bean instances and the interceptor instances to get notified on events
related to their life cycle. This notification is based on callback functions that are being called by
the container after creation and activation, and before destruction and passivation.

      JSlave does not support the use of external callback listeners like postulated in the
      specification; code for this purpose has been prepared but barely been tested.

The callback methods are configured by the use of the meta information (e.g. by using annotations)
and are slightly different for beans and interceptors. While the callback methods for beans do not
have an argument, callback methods for the interceptors expect an implementation of
InvocationContext as the only argument (see LoggingInterceptor in the Course
Administration Sample for an example).

Activation and Passivation

For stateful bean instances the EJB specification allows the so-called passivation, like described in
[ejbspec], 4.2. Passivation in this context means, that the container is allowed to write the
Conversational State of a stateful bean instance to any kind of secondary storage and thus is able to
reduce the memory consumption of the working set.

As the EJB specification does not require bean and interceptor instances to implement the
Serializable interface needed for the Java Serialization API, it is the task of the Bean Provider



                                                  66
                                                                     JSlave - Life Cycle Callbacks"



and the Container Provider to make the conversational state serializable. The Bean Provider has to
make sure that the fields of a bean instance and its associated interceptors contain only values like
defined in [ejbspec], 4.2.1 after the prePassivate() method has been called. The Container
Provider is then responsible to replace container-controlled values (e.g. the EJBContext
implementations or client view proxies) by serializable objects.

JSlave uses the object replacement technique of java.io.ObjectOutputStream and
java.io.ObjectInputStream to replace container-owned objects by instances of
Replacement, that serves as an index to a ReplacementMap (containing the real objects and
staying unserialized in the memory of the container).




Illustration 15: Passivation of a stateful bean BeanImpl




                                                           67
                                                                       JSlave - Life Cycle Callbacks"



The passivation is a three-stage process:

    1. For a bean instance and all associated interceptors ConversationalState objects are
        constructed,        containing   the   values   of   all   non-transient   fields;   like   in
        DependencyInjector the Field.setAccessible() method is used to get access
        to public, protected, package, and private fields.

    2. The ConversationalState objects are serialized to a file in the {server}/work
        folder   by     a    StatefulBeanOutputStream.             StatefulBeanOutputStream
        overrides the replaceObject() method of java.io.ObjectOutputStream to
        replace objects of certain types by the already mentioned indexes into the
        ReplacementMap.

    3. After the Serialization has been performed the container removes all references to the bean
        and interceptor instances and allows the Garbage Collection to remove these objects from
        memory.

The activation is the reverse process and will be called on demand (i.e. when a business method is
being called). Like the passivation the activation is performed in three steps:

    1. The file containing the serialized ConversationalState objects is being loaded by
        StatefulBeanInputStream. The overwritten resolveObject() method replaces
        all occurrences of Replacement by the related objects from the ReplacementMap.

    2. New instances of the bean class and the associated interceptor classes are being created
        using the default constructor.

    3. The field and value pairs from the ConversationalState objects are then being
        “injected” into the bean instance and the interceptor instances.

Before passivation and after activation the related callback methods of the bean instance and the
interceptor instances are called to allow the Bean Provider to prepare and restore the instances'
fields, respectively.




                                                   68
                                                                       JSlave - Life Cycle Callbacks"



Business method call

Before the actual business method like defined in the bean class can be executed, various other
steps have to be completed in order to prepare the execution of the bean's code.

     The steps described in this chapter are the steps that are performed by the BeanInstance
     instances; but at that point a business method call has already run through various stages
     (e.g. marshalling, transmission, unmarshalling, client view call, connection handling,
     processing        by       BeanInstanceManager              and       execution      by        the
     BeanExecutionManager).

An incoming business method call will be processed like the following:

   1. Activation (StatefulBeanInstance only)

       If the StatefulBeanInstance has been passivated formerly it will be activated again
       by loading the serialized values from the hard disk and reconstructing the bean and
       interceptor instances.

   2. Injection of java:comp/EJBContext (StatelessBeanInstance only)

       A StatelessBeanInstance can be called by a different Connection on every
       invocation; as each Connection has its own EJBContextImpl it is necessary to redo
       the Dependency Injection of java:comp/EJBContext for the bean instance and all
       interceptor instances.

Security check

       Before a business method can be called the caller's principal undergoes a security check to
       find out, if he has at least one of the allowed roles for an execution. If the caller is not
       allowed to call this bean method BeanInstance will throw a EJBAccessException.

   3. Building of the the interceptor stack

       As the interceptor stack can look different for every business method depending to the meta
       data, on every business method invocation the stack of interceptors has to be built again.




                                                 69
                                                                        JSlave - Life Cycle Callbacks"



    4. Invocation of the interceptor stack

           Finally the invocation of the interceptor and bean code can be started. The bottom of the
           interceptor stack always is the called bean method itself.


4.4 Security check

Every connection is established by a certain principal, and a principal can be assigned to one or
more roles. Also a bean's business method can have permitted roles, i.e. a principal is only allowed
to execute a method if it is assigned to at least one of the allowed roles.

Depending on the type of distribution network a business method call is made from, there are
different ways to pass the user credentials that are used to get a principal. The EJB specification
does not specify the security architecture, so JSlave uses its own (basic) technology, like specified
in IV.6.

The container throws a EJBAccessException if the caller's principal is not allowed to execute
a business method.


4.5 Interceptor Stack

The interceptor concept offers a easy way for the Deployer to extend or change the behavior of an
existing bean. Every interceptor therefore has the possibility to surround the next interceptor (or
bean) call, and can change parameters or return values, or simply prevent the next interceptor (or
bean) from being processed.

The so-called interceptor stack will be computed every time a business method is called, as by using
meta data the Bean Provider, Application Assembler, and Deployer can control the ordering of the
stack. The bottom-most entry of the interceptor stack always is the business method of the bean
itself.

          In fact, JSlave in the current version does not process the meta data to manipulate the
          interceptor    stack     on      method      level;     the   corresponding     annotations
          @ExcludeClassInterceptors,                   @ExcludeDefaultInterceptors,                or



                                                     70
                                                                      JSlave - Interceptor Stack "



        @Interceptors for a method are ignored. Thus, the interceptor stack will look similar for
        every method within a bean class.

The aroundInvoke() method of an interceptor is called with an implementation of the
InvocationContext as parameter. By using the methods of InvocationContext the
interceptors are able to manipulate the parameter list of the business method, to pass values to
further interceptors, or to simply prevent the next interceptor (or bean) method from being
processed. To proceed with the next deeper level within the interceptor stack, the interceptor must
call InvocationContext.proceed().

Example
In this example a BeanClass defines two interceptors of the class Interceptor1 and
Interceptor2.
 @Stateless
 @Interceptors({Interceptor1.class, Interceptor2.class})
 public class BeanClass extends BusinessInterface {
        public void method() {
                ...
        }
 }

 code 14: BeanClass.java

When the business method is to be executed the interceptor stack will be built and executed like
this:




                                                71
                                                                                  JSlave - Interceptor Stack "




           Illustration 16: Invocation of the BeanClass.method() while using the two interceptors




5 Distribution subsystem

The part of JSlave that is responsible for externalizing the functionality of the deployed session
beans is called distribution subsystem. RMI and web services count as a part of the distribution
subsystem, while internally used connections that have been established using JNDI lookup or
Dependency Injection are separate.




                                                       72
                                                                     JSlave - Distribution subsystem"




Whenever new beans are deployed, the DistributionManager gets called and in turn calls the
different Distributors (currently RMIDistributor and WebServiceDistributor) to
distribute a bean's functionality via the related distribution network.


5.1 RMI

For exporting the remote business methods of a session bean via RMI, JSlave uses Sun's standard
RMI implementation, although this implementation is at some points not suitable for exporting the
remote interfaces like specified in the EJB specification.

The main disadvantage of Standard RMI is the need for the Remote interface: Only interfaces
extending java.rmi.Remote are exportable using RMI. As the EJB specification does not




                                                   73
                                                                                      JSlave - RMI"



require the business interfaces of session beans to extend the Remote interface, a lot of effort has
to be spent on exporting the beans' functionality.

       This problem JSlave has in common with the other EJB container implementations; for
       instance do JBoss, EasyBeans and even GlassFish use similar workarounds to export the
       business methods over RMI. As a result a client using RMI needs a vendor-specific JNDI
       extension and never can use the plain RMI API.

In JSlave the TRMI project is used to export non-Remote interfaces via RMI. For various reasons
TRMI had to be extended and changed, like described in IV.5.1.3 . Additional customizations of
RMI were necessary and are described in the following chapter, and to allow the clients to pass the
user credentials to the server an extension covers the authentication mechanism.

All of these changes and extensions are contained in a separate project called trmijndi. The reason
for not incorporating the trmijndi classes in the JSlave project is that a trmijndi.jar has to be
generated and copied to {server}/lib. It includes the functionality of TRMI, a JNDI extension
allowing the clients to establish a TRMI connection to the server using JNDI, and the classes that
are necessary to use the authentication mechanism of the server.


5.1.1 RMI Customizations

In the first place an own implementation of the RMI registry server must be used instead of the one
that is built into the RMI packages from Sun. The reasons for that are:

   ●    Sun's RMI registry server like returned from LocateRegistry.createRegistry()
        does return a registry that cannot be stopped in a programmatic way, but JSlave must be able
        to close the RMI distribution network at a specific point during the shutdown process.

   ●    Usually an object is bound to the RMI registry and returned on every lookup, but JSlave
        needs a registry that can return a new object on every lookup (i.e. a new client view proxy).
        The RMI Activation technology cannot be used as the object creation happens on client-
        side.




                                                     74
                                                                                       JSlave - RMI"



Secondly, the combination of the use of ClassLoaders for the various enterprise application archives
and the use of TRMI made a changed RMIClassLoaderSpi necessary. Actually
RMIClassLoaderSpi is a class that is responsible for passing information about codebases from
server to client; in JSlave ClassLoaderSPI removes all information about codebases, and thus
prevents the server from using the wrong ClassLoader.

In the third place a couple of system-wide properties must be changed in order to change the default
behavior of the RMI implementation from Sun. The purpose of these changes is to fasten up the
Distributed Garbage Collection and to make the processes that occur on connection closure are
more obvious. Although this customization is not mandatory it is very useful, as otherwise the
disconnected client views would be deleted after at least two hours delay.

     Currently there is a bug in the RMI subsystem of JSlave that prevents the closed RMI
     connections from being cleanup up. A delay of approximately 15 minutes has to be taken into
     account.


5.1.2 TRMI

TRMI stands for Transparent Remote Method Invocation and is a open source project available
under http://trmi.sourceforge.net. It extends the standard RMI by allowing

   1. the    invocation   of   methods    of   any    interface   (not   just   interfaces   extending
       java.rmi.Remote), and

   2. a centralized processing of occurring RemoteExceptions during method invocation.

For JSlave the first point is from high importance as it enables a program to export non-Remote
interfaces via RMI.

TRMI works by wrapping the object that is to be exported by a RemoteObjectWrapper.
RemoteObjectWrapper together with a StubInvocationHandler makes a call via RMI
possible, or – in other words – tunnels the RMI connection.




                                                 75
                                                                                                  JSlave - RMI"



When on server-side a object is to be bound to the RMI registry, TRMI checks if the object
implements the Remote interface. If not, a new instance of RemoteObjectWrapperImpl is
constructed and bound to the registry instead of the actual object. If on the client-side a lookup
operation      returns       a     RMI       stub         implementing    RemoteObjectWrapper,                a
java.lang.reflect.Proxy                     object        is   constructed    using        an     instance   of
StubInvocationHandler for method delegation. The resulting flow of calls on a method of
the original object looks like the following:




Illustration 17: Call stack resulting from RMI and TRMI

    1. The client uses the java.lang.reflect.Proxy object to call a method.

    2. The        java.lang.reflect.Proxy                      object    delegates    to        its   associated
        StubInvocationHandler.




                                                          76
                                                                                         JSlave - RMI"



    3. The      StubInvocationHandler               calls   the    invokeRemote()           method     of
         RemoteObjectWrapper on the RMI stub of RemoteObjectWrapperImpl.

    4. RMI does the marshalling, transmission, and unmarshalling of the method call.

    5. On server-side, the invokeRemote() method of the RemoteObjectWrapperImpl is
         called by the RMI skeleton.

    6. RemoteObjectWrapperImpl calls the exported method of the actual object.

        In JSlave the object itself is a proxy instance acting as client view proxy instead of the actual
        bean instance.


5.1.3 TRMI Customizations

As already mentioned before some changes and extensions had to be made on the TRMI project;
these have been implemented in a from JSlave seperate project called trmijndi. To prepare the
original TRMI project for the use with JSlave, it had to be edited at various points:

    ●    trmi.Naming originally offered its functionality by public static methods and has
         been changed to instance methods. The Singleton pattern has been applied for the new
         trmi.Naming to still allow the centralized access.

    ●    The use of java.rmi.Naming has been replaced by using a configurable registry. This
         makes trmi.Naming more flexible and allows the use of AuthenticatedRegistry
         like described in the next chapter.

    ●    Support for classes from different ClassLoaders has been introduced.

    ●    A new recovery strategy factory has been implemented to avoid infinite loops from the
         original TRMI project.

    ●    Bugfixes of some smaller bugs.

These changes have been done by changing the original source code of TRMI; thus the original
library is not part of JSlave.




                                                    77
                                                                                  JSlave - RMI"



5.1.4 Authentication Extension

Neither RMI nor TRMI have a built-in technique to pass authentication data from client to server,
so JSlave implements its own authentication mechanism.

On server-side an implementation of the Authenticator interface is bound to the name
“de.fhr.jndi.trmi.Authenticator”. If its authenticate() method is called with
valid user credentials, it returns a AuthenticatedRegistry instance that has been constructed
with the associated principal. AuthenticatedRegistry will return a client view like
RMIRegistry on every lookup, but set the the principal of the related connection to the
associated principal.

If on client-side the TRMIInitialContextFactory can find user credentials in its
environment          (values        for        java.naming.security.principal                and
java.naming.security.credentials), it will lookup the Authenticator and call its
authenticate() method with these user credentials. From then on the returned Registry
will be used rather than the initial one.


5.2 Web Services

The        web          service      distribution        subsystem   is    packaged       within
de.fhr.ejb3container.distribution.webservice and contains three classes:




                                                    78
                                                                           JSlave - Web Services"




Illustration 18: UML diagram web services



The WebserviceDistributor.distribute() method is called whenever a bean class is to
be distributed by JSlave. If a bean is annotated correctly as a web service (using @WebService in
front of the bean class) a new WebserviceInvocationHandler instance is created that will
be called on every business method invocation on that bean.

The WebserviceInvocationHandler is used to create a proxy for the bean. This proxy in
turn is then published via Sun's JAX-WS Reference Implementation as a web service, using the
bean name to bind the web service endpoint to a certain URL, that can be configured using the
JSlave configuration file. For instance, if a bean named BeanImpl is provides web methods it will
be published to http://localhost:8080/BeanImpl (if the default configuration is used).

      The creation of the WSDL document and the implementation of the necessary server
      infrastructure is performed by JAX-WS RI and is not subject to this document.

The proxy mentioned above is not created using java.lang.reflect.Proxy but the
manually created proxy (like described in IV.2.4), since JAX-WS RI uses annotations to generate
the WSDL document rather than a web method interface. Thus, when the web service endpoint is



                                                79
                                                                            JSlave - Web Services"



created from the proxy instance, it has to contain the same annotations as the actual bean class.
java.lang.reflect.Proxy is neither capable of creating a proxy from a bean class nor of
carrying on the annotations from the implementing interfaces and classes. Therefore a manually
created proxy must be used.

An           incoming          business          method            call           triggers       the
WebserviceInvocationHandler.invoke()                     method,    that   will     create   a   new
Connection, call its handleCall() method, and close the Connection.

The SoapMessageHandler class is used for authenticating a user and allowing the security
subsystem to work properly. SOAPMessageHandler is implementing the SOAPHandler
interface and called on every incoming SOAP request. It analyses the HTTP header of the SOAP
request and extracts the user credentials using the Basic HTTP Authorization mechanism defined in
[rfc2617].

     If the Basic HTTP Authorization mechanism is used a HTTP client extends a HTTP request by
     a HTTP header field called Authorization. The value of this field is structured like this:
Basic username : password


     The substring after “Basic ” is Base64 encoded and has to be decoded on server-side.


6 Security Subsystem

The task of the security subsystem in JSlave is to ensure that a user has only access to business
methods he is allowed to. The security concept like specified in [ejbspec], 17 is based on a
principal-role system that is similar to the user-group system of UNIX platforms:

A user is mapped to a so-called principal, which is part of one or more so-called roles. The user is
only allowed to invoke a business method if he is part of at least one of the allowed roles of this
method.

The functionality to ensure this behavior in JSlave is spread into various parts. BeanInstance
and its subclasses will ensure during the business method invocation, that principals are only




                                                80
                                                                          JSlave - Security Subsystem"



allowed to call business methods they have the proper roles for. The classes of the distribution
subsystem offer a way to pass the user credentials from the client to the server in order to
authenticate a user. The classes in the de.fhr.ejb3container.security package contain a
user-role database to verify the user credentials and to do find the roles a user is part of.




Illustration 19: UML diagram user management



The      BasicUserDatabase                class    uses      simple      text     files     (stored   in
{server}/users.properties and {server}/roles.properties) to load the user
credentials, consisting of username and password, and principal-to-role assignments. These
files are standard property files that have a format similar to that of the JBoss
UsersRolesLoginModule (but do not support so-called rolegroups). JSlave already contains some
sample users and roles to be used with the sample applications.




                                                   81
                                                                       JSlave - Security Subsystem"



       The security subsystem of JSlave in the current version is not meant to reach production
       quality. In fact it deviates at many points from the specification and is much more a way to
       test the principal-role behavior, especially since security like specified in the EJB
       specification covers much more aspects (e.g. isolation of bean and container code).


7 Multithreading

The fact that JSlave incorporates multiple parallel servers (RMI, web services, JMX) leads to a big
number of concurrently active threads, each using and sharing data structures with the container
implementation. That is why a lot of effort must be spent on a proper threading architecture and the
resulting synchronization mechanisms.

The following thread types are active concurrently:

   ●    Main thread

        JSlave runs in its main thread when it has been started from command line. After the startup
        the main thread just waits for a keyboard command to shut down again; that will trigger
        various mechanisms that use the data structures of the container.

   ●    AutoDeployer thread

        The server observes the {server}/deploy folder continuously to find new, changed,
        and removed enterprise application archives. This observation is performed by using a
        Timer thread that will compare the contents of the {server}/deploy folder every
        1000 milliseconds; a file change either will result in a deployment or undeployment of an
        enterprise application archive.

   ●    (Distributed) Garbage Collection

        The           Garbage             Collection        thread          can      call        the
        ClientViewInvocationHandler.finalize() method that is used to close a
        internal or external connection.

   ●    RMI threads



                                                       82
                                                                                 JSlave - Multithreading"



         Sun's RMI implementation uses various threads for the processing of incoming RMI
         lookups and calls, and for implementing the Distributed Garbage Collection.

    ●    Web service threads

         Sun's reference implementation JAX-WS RI uses various threads for the processing of
         incoming SOAP requests.

    ●    JMX threads

         The JMX subsystem as well can start various threads for the processing of incoming calls,
         like passivating beans or destroying the stateless bean pool.




Illustration 20: Different threads and some of the container's data structures



All of these threads use data structures of the server, especially the BeanInstance instances. To
gain back control of the execution of BeanInstance code, BeanExecutionManager has
been implemented. BeanInstanceManager therefore never calls methods of BeanInstance
directly but uses an implementation of the Callable interface, puts it to the job queue of
BeanExecutionManager, and waits for its completion. Since all calls to methods of
BeanInstance are made by using an appropriate method in BeanInstanceManager, the
technique of using Callable objects instead of direct method invocation is only necessary in
BeanInstanceManager.




                                                           83
                                                                              JSlave - Multithreading"



BeanExecutionManager uses a extension of ThreadPoolExecutor to put incoming calls
to a job queue and process it by an free thread in its thread pool. The public methods of the
BeanInstance classes are marked with the keyword synchronized, so that an instance of
BeanInstance can only be active in one thread at a time. All BeanInstance methods
containing calls to the actual bean and interceptor code are therefore only invoked in threads of the
BeanExecutionManager's thread pool.

As by-product of the BeanExecutionManager it is possible to find the BeanInstance being
currently processed; an information that is necessary for the Bean Environment Multiplexing (see
V.1 ).


8 Monitoring and Logging

The Java Management Extensions(JMX) provide an easy way of managing Java applications.
JSlave uses JMX for monitoring the following aspects:

   ●     Bean instances

   ●     RMI registry

   ●     Web service endpoints

   ●     Deployed applications, beans

   ●     Active client connections

Additionally also methods for configuring the amount of active bean instances are available through
JMX. It is possible to destroy the current stateless bean pool and passivate all stateful bean
instances.

All these aspects are managed by MBeans. MBean objects can be registered at a JVM wide
platform server and thus are available for monitoring and configuring JSlave through other Java
applications remotely. MBean classes must implement an MBean interface. This interface must be
named according to the following pattern: [MBean-classname “MBean”]. All methods
defined in this interface are then available via the platform MBean server.



                                                 84
                                                                JSlave - Monitoring and Logging"



A typical MBean in JSlave looks like this:

public class NamingConfig implements NamingConfigMBean {
       RMIDistributor rmiDistributor;
       WebserviceDistributor wsDistributor;

        public NamingConfig(DistributionManager manager){
               //... Constructor
        }
        public List<String> getRMIInterfaces() throws AccessException, RemoteException {
               List<String> result = new ArrayList<String>(bindings.length);
               //... Reading the RMI registry
               return result;
        }
        public List<String> getWebServiceEndpoints() {
               List<String> result = new ArrayList<String>();
               //... reading all web service endpoints
               return result;
        }
}

code 15: NamingConfig.java

The corresponding MBean interface looks like this:

public interface NamingConfigMBean {
       public List<String> getRMIInterfaces() throws AccessException, RemoteException;
       public List<String> getWebServiceEndpoints();
}

code 16: NamingConfigMBean

Typically a MBean in JSlave monitors one specific service class. Like the example MBean provides
methods for monitoring the DistributionManager MBean. The following MBeans are
defined in JSlave:

         MBean                Corresponding service class                       Description
ConnectionConfig             ConnectionManager               Shows        all     active      connections,
                                                             including the corresponding client
                                                             information.
ContainerConfig              Container                       Show    all        deployed      beans   and
                                                             applications.
BeanInstanceConfig           BeanInstanceManager             Show all bean instances. Provides
                                                             methods for destroying the stateless
                                                             pool and passivate stateful bean
                                                             instances.




                                                 85
                                                             JSlave - Monitoring and Logging"



NamingConfig              DistributionManager              Show all available RMI remote
                                                           interfaces and web service endpoints.


JDK already offers an application for viewing and configuring MBeans: JConsole. This application
shows all MBean that are available in a Java application and provides methods for viewing and
modifying MBean attributes(through it's getter and setter methods) and invoking the methods
specified in the MBean interface.




The MBeanManager service class registers MBean objects at the platform MBean server




                                              86
                                                                 JSlave - Monitoring and Logging"



The main purpose of the JSlave logging output is to give an overview of the processes running
inside the application container.

There are two types of logging output in JSlave. The first one is the direct console output. It shows
only the most important information, e.g. when an EAR file is deployed or when proxies are
registered at the naming services.

The second logging output is more detailed and stored in three files in the {server}/log/
directory:

    ●    startup.log: server startup information

    ●    deployment.log: deployment logging

    ●    runtime.log: logging of incoming requests.

All logging output is created by the Java Logging API. Console output is generated directly in the
JSlave sources by the info() method of the Logger class. Unless a logging.properties
file is submitted as JVM parameter, the console output format in JSlave is controlled by the Log
class.

For all detailed logging output AspectJ is used. AspectJ is an extension of the Java SE for aspect-
oriented programming. The advantage of AspectJ in JSlave is that the logging features can be seen
as a separate aspect. Thus the actual JSlave sources become more readable because they are mostly
free of any logging methods. These methods are contained in several aspects.

The following aspects are defined in JSlave for creating logging output:

                Aspect                                        Logging output
BeanLogger                              Creation of new Bean classes, creation of naming context
ClientViewLogger                        Creation of new client views
ConnectionLogger                        Creation of new Connections, incoming calls.
DeployLogger                            Creation of work directories, meta data, classloaders, etc.
DistributionLogger                      Binding of proxies to naming services
GeneratorLogger                         Generation of proxies




                                                 87
                                                                  JSlave - Monitoring and Logging"



InstanceLogger                          Creation of bean instances, incoming business method
                                        calls.
RegistryLogger                          lookups
ServiceLogger                           startup and shutdown of service classes


A typical aspects looks like this:

public aspect RegistryLogger {
       pointcut lookup() : execution(* *Registry.lookup(..));


        after(): lookup(){
               Logger log = AppServerLogger.getRuntimeLogger();

                Object[] args = thisJoinPoint.getArgs();
                String name = (String)args[0];

                log.info(thisJoinPoint.getThis().getClass().getSimpleName()
                               + " lookup " + name);
        }
}

code 17: RegistryLogger.aj

The fields and methods of the intercepted class can be retrieved by using reflection on the
thisJoinPoint object.




                                                  88
                                                                         JSlave - Difficult hot spots"




V Difficult hot spots
This chapter gives an overview of some more difficult parts, that JSlave and other EJB
implementations suffer from and that one would not expect by reading the specification. Besides
these "hidden" difficulties there are of course the very obvious ones, like the vast size of the
specification(s) and the extensive usage of the Reflection API, to name but a few.


1 Bean Environment Multiplexing

The specification explicitly allows the Bean Provider to use the programmatic JNDI interface to
lookup resources, beans, and other entries from the bean's environment ([ejbspec], 16). Although
every bean class has its own environment, the specification allows every bean to access its
environment by a JNDI lookup of java:comp. On top of this a lookup of the SessionContext
instance   (which    is   unique   for   each   bean   instance)   has    to   be    provided   under
java:comp/EJBContext.

public void businessMethod() {
       InitialContext initialContext = new InitialContext();
       Bean b = (Bean) initialContext.lookup("java:comp/env/bean");
       SessionContext s = (SessionContext) initialContext.lookup("java:comp/EJBContext");
}


To allow this, JSlave has to multiplex the java:comp context for each bean class as well as the
java:comp/EJBContext for each bean instance. The multiplexing is done by using the active
thread (using Thread.currentThread()) and looking up the bean instance that is currently
being executed in this thread.

      A multiplexing based on threads and instances seems to be a very complicated attempt to
      accomplish the java:comp diversity. But in fact other EJB implementations like JBoss,
      EasyBeans, and even Glassfish use a similar strategy.

Within JSlave the invocation of the java:comp multiplexer is done by the using the JNDI API
NamingManager.setInitialContextFactoryBuilder()                                      with          an




                                                 89
                                                            JSlave - Bean Environment Multiplexing"



InitialContextImpl, while the java:comp/EJBContext multiplexing is performed
within EJBContextReference.


2 Code generation

Whenever a bean's functionality is to be provided to other beans or remote systems, it is never the
bean instance itself that is returned but a client view proxy, that first will invoke the container's
services (like security checks, interceptor calls, etc.) and at the very end of the call chain will invoke
the actual bean code.

Although proxy generation is part of the Reflection API and embedded into Java since version 1.3,
JSlave uses its own proxy generation methods at some points. This is due to the fact that
java.lang.reflect.Proxy does

    ●    neither create proxies for classes (interfaces only)

    ●    nor copy annotations from the interfaces into the created proxy.

As the JAX-WS library needs annotations to create the WSDL description of a web service
endpoint, it was necessary to create a proxy generator that fulfills this requirements.

The process of proxy generation can be divided into three parts: reading class meta data,
annotations, methods, generate the new proxy class out of this information and compile the proxy
class.

Reading information about classes, methods and annotations can be easily done by using the Java
Reflection API. All methods for reading elements of classes are provided by the
java.lang.reflect.Class class.

The Reflection API also provides methods for generating string representations of the
corresponding class element (toString(), getName(), getSimpleName()). However these
methods are often not suitable for generating code. E.g. the toString() method of the
Annotation interface generates the following string when reading the @WebMethod annotation:




                                                    90
                                                                           JSlave - Code generation"




@javax.jws.WebMethod(action=,operationName=,exclude=false)


This annotation cannot be compiled with a standard Java compiler.

Thus in most cases own methods for printing the strings are needed. The following method prints an
annotation properly. It uses an instance of the Annotation Class object to write all information.
The method first writes the annotation name. Then it checks if there are any properties specified in
this annotation, if not the string is complete. The last step is to read and write all property values,
the invoke() method is used for this step.


private void writeAnnotations(Annotation[] annotations) throws Exception{
       for(Annotation annotation : annotations){
               Class<?> annotationClass = annotation.annotationType();
               String strAnnotation = "@" + annotationClass.getName();

                Method[] methods = annotationClass.getDeclaredMethods();
                if(methods.length > 0){
                       for(int i = 0; i<methods.length;i++){
                         Object annotationProperty = methods[i].invoke(annotation, (Object[]) null);
                               //write the actual property value...
                       }

                insertLine(strAnnotation);
        }
}

code 18: writeAnnotations method in ClassWriter.java

The last step for the proxy generation is to compile the generated class. This can be done
automatically by using the com.sun.tools.javac.Main class. The corresponding library
tools.jar must be in the JSlave classpath.

      That explains the need to specify the path to a JDK directory in JBoss; it uses a similar code
      generation feature and needs the path to a valid JDK1.5/lib/tools.jar.


3 RMI limitations

To provide the bean's functionality via RMI a lot of customizations of the RMI system have to be
made. Like described in IV.5.1 the main difficulty is the need for java.rmi.Remote interfaces




                                                       91
                                                                         JSlave - RMI limitations"



when a object is to be bound to the RMI registry, because the EJB specification does not explicitly
require a bean's remote interface to extend java.rmi.Remote.

JSlave and all other EJB container implementations therefore either extend the basic RMI system by
some vendor-specific code – JSlave uses a customization of TRMI here – or simply do implement
an own RMI-similar protocol (e.g. EasyBeans). Usually a JNDI service provider for the used
distribution technology is made available for the use in clients, so that the change of the EJB
container implementation does only need a changed jndi.properties in the client's classpath.


4 Authentication

Even though the EJB specification covers the authorization mechanism in detail, it does not specify
a certain authentication system. That means, that it is left to the container provider, how user
credentials or other information can be used to identify a principal, while it is exactly clarified,
which methods these principals and roles can call.

Since both RMI and SOAP do not cover the authentication procedure either, there is a need for an
own authentication system for the use with in EJB containers. JSlave in its current version does
therefore implement a very basic authentication mechanism for both the RMI and the WebService
distribution system.

     Most of the EJB container implementations do have one or more different authentication
     systems, and it is the Administrator's task to establish a connection between the container's
     authentication and the enterprise's user management system.




                                                92
                                                                               JSlave - User guide"




VI User guide
This guide describes installation, administration and monitoring of JSlave. Some example
applications are provided for showing several features of JSlave and EJBs. The final distribution of
JSlave contains the actual JSlave application container, external software(e.g Eclipse, JDK1.5),
some sample applications and the JSlave and trmijndi sources.


1 Installation

JSlave can be installed locally by simply copying all files(contained in the attached distribution of
JSlave) to a local drive. It must be ensured that the user running JSlave has write privilege for the
{server}/deploy/ and {server}/work/ directory.

JSlave needs J2SE 5.0 JRE as runtime environment and JDK 5.0 for compiling proxies. JDK
5.0(which includes the JRE) is included in the distribution in the software/jdk1.5/ directory
of the distribution.

The actual home directory of JSlave can be set by submitting a folder as command line argument of
JSlave. Normally the home directory is set to the server/ directory in the JSlave project
directory(code/appserver/) .

The home directory contains a server.properties file which is responsible for configuring
JSlave. The content of the original server.properties file is listed below:




                                                 93
                                                                            JSlave - Installation"



# Server Configuration File

# Directory containing the EJB archives. This directory will be observed to enable
# deployment/undeployment by file adding/removing.
deployDir = deploy

# Directory where the contents of the EJB archives will be extracted to and the
# generated classes will be written to
workDir = work

# Directory containing all libraries which will be in the class path of the EJBs
clientLibDir = lib

# Port number for the TRMI registry
trmiPort = 1099

# URL where the webservice endpoints will be published to
uddiUrl = http://localhost:8080

# Basic user database; 2 plain property files containing username-password and
# username-roles, respectively
basicUsersFile = users.properties
basicRolesFile = roles.properties

code 19: server.properties


The deployDir, workDir and clientLibDir can be set to any desired directory. However it
must be ensured again that the user has the privilege to create new files in deployDir and
workDir.

The user.properties and roles.properties files specifiy the security settings of
Jslave(unless specified differently in server.properties). User.properties is the user
database of JSlave containing user names and their passwords in the following format:
user = password

# Basic User Database

admin = admin123
rainer = reniar
sebastian = naitsabes
jobst = fritz

code 20: user.properties


roles.properties specifies the roles that a user belongs to. The format is:
user = role1,role2,...,roleN




                                               94
                                                                             JSlave - Installation"



# Basic Role Database

admin = admin,author,user,student,professor
rainer = admin,user,student
sebastian = author,user,student
jobst = user,professor

code 21: roles.properties




2 Server

2.1 Startup, Shutdown

JSlave can be started on Windows platforms by the Start Server.bat script. This script
automatically includes all needed jar archives. The script uses the jdk1.5 runtime contained in the
software/jdk1.5/ directory of the distribution. For unix platforms the java runtime and the
path separator character has to be changed.

cd code\appserver

..\..\software\jdk1.5\bin\java.exe -Dcom.sun.management.jmxremote -classpath bin
;lib\jta-1_1-classes.jar;lib\ejb-3_0-api.jar;lib\jaxrpc-1_1-fr-spec-api.jar;lib\
jsr250-api.jar;lib\activation.jar;lib\FastInfoset.jar;lib\http.jar;lib\jaxb-api.
jar;lib\jaxb-impl.jar;lib\jaxb-xjc.jar;lib\jaxws-api.jar;lib\jaxws-rt.jar;lib\ja
xws-tools.jar;lib\jsr173_api.jar;lib\jsr181-api.jar;lib\resolver.jar;lib\saaj-ap
i.jar;lib\saaj-impl.jar;lib\sjsxp.jar;lib\stax-ex.jar;lib\streambuffer.jar;lib\t
rmijndi.jar;lib\tools.jar;lib\aspectjrt.jar de.fhr.ejb3container.ApplicationSer
ver


cd..

cd..

code 22: Start Server.bat

As mentioned in VI.1 the home directory of JSlave can be modified by submitting the desired
directory as command-line argument of the ApplicationServer main class. The command-
line   argument        has   to   be   inserted    into   Start       Server.bat       after    the
de.fhr.ejb3container.ApplicationServer                     keyword.




                                                  95
                                                                            JSlave - Startup, Shutdown"



JSlave can also be started by using the Eclipse IDE. Therefore the Eclipse project contained in
code/appserver/ has to be imported in Eclipse. An Eclipse distribution for windows is also
part of the JSlave distribution, it is included in the software/ directory. The advantage of starting
JSlave with Eclipse is that the server can also be debugged.

The server is stopped by pressing return on the server console.


2.2 Deploying applications

EAR files and EJB-JARs can be deployed by copying them to the deploy directory(normally
{server}/deploy/). They can be undeployed by deleting them from the deploy directory. At
startup JSlave deploys all applications contained in the deploy directory. At the shutdown JSlave
undeploys all deployed applications.

Upon deploying an application JSlave writes information about the deployed application on the
console. More detailed information about the deployment process can be found in the
deployment.log file contained in the {server}/log/ directory(see VI.2.4).


2.3 Monitoring

JSlave can be monitored using JConsole. JConsole can be started by the Start JConsole.bat
script. JConsole can be also started directly in the bin/ directory of the current JDK. Upon startup
a     connection   to   the   JSlave        application    has    to   be    established,   choose   the
de.fhr.ejb3container.ApplicationServer class and click on connect to do that.

JConsole provides several tabs for showing the current memory usage, threads, loaded classes, etc.
The      JSlave    MBeans     can      be      found      in     the   MBeans      tab.     Expand   the
de.fhr.ejb3container.jmx.* elements at the MBeans tree to the right to see all available
JSlave MBeans.

At the moment 4 MBeans can be monitored: ConnectionConfig, ContainerConfig,
BeanInstanceConfig, NamingConfig.




                                                    96
                                                                                JSlave - Monitoring"



The ConnectionConfig MBean shows the following screen:




The Clients fields shows all client hosts that are currently connected to JSlave. The Connections
fields shows all active connections(double click on the field to expand the view) from client hosts
to beans. The ConnectionCount field shows the overall count of all active connections. Note that
JConsole doesn't refresh the view automatically, the user has to click on the refresh button.




                                                  97
                                                                             JSlave - Monitoring"



The ContainerConfig MBean shows the following screen:




The Application field shows all applications that are currently deployed in JSlave. The Beans field
shows all available EJBs.




                                                98
                                                                              JSlave - Monitoring"



The BeanInstanceConfig MBean screen looks like this:




The BeanInstances field shows all bean instances that are currently present in JSlave. The
StatefulInstances and StatelessPool divide the instances in the BeanInstaces field according to their
type. StatefulCount and StatelessCount sum up the overall count of the corresponding bean
instances.

The Policy field shows the current policy for stateless bean instance creation. If it is on “KEEP”
new instances are only created if there is nor instance currently available for a request. The Policy
“CREATE” creates a new stateless bean instance upon every request. However the Policy
“CREATE” feature has only been tested barely, it is not recommended to use it.



                                                 99
                                                                          JSlave - Monitoring"



There are also several operations available for the BeanInstanceConfig Mbean(click on the
Operations tab):




The destroyStatelessPool operation clears the stateless bean pool by deleting all stateless bean
instances. The passivateStateful operation passivates all active stateful bean instances. These
features can be used for cleaning up JSlave's memory.

The setPolicyKeep and setPolicyCreate(not recommended!) operations set the Policy field to the
corresponding value.




                                               100
                                                                               JSlave - Monitoring"



The last MBean, NamingConfig shows the content of the JSlave naming services:




The RMIInterfaces field shows all remote interfaces that are registered in the RMI registry. The
names shown are the names that are bound to the RMI registry. The WebServiceEndpoints field
shows all endpoints that are currently registered in the UDDI, including the address of the endpoint.


2.4 Logs

The most important information about the current JSlave session is shown on the console. It shows
startup information, deploy and undeploy of applications and the creation of new connections and
bean instances.




                                                101
                                                                                       JSlave - Logs"



The following console output is created upon startup:
4:57:17 Server starting up...
//... deploy of applications
14:57:26 Server started.
Press return to shutdown the server...


Further startup information can be found in the startup.log file in the {server}/log/
directory.

Upon deployment of an application the following output is created on the console:

14:57:22     Start deploying server/deploy/calculator.jar
14:57:24     Bound bean calculator.Calculator to TRMI registry at Calculator
14:57:25     Distributed webservice at http://localhost:8080/Calculator
14:57:25     server/deploy/calculator.jar deployed.


The more detailed output in the deployment.log file shows all internal steps that are performed
during deployment of an application, e.g. creation of meta data, class loaders, bean classes, etc.

Incoming calls are also logged on the console and in the runtime.log file. On the console only
the creation of new connections and bean instances is logged:

15:02:52 Incoming new connection for bean AppServerTestBean
15:02:53 New instance of AppServerTestBean


The runime.log file shows also lookups for remote interfaces and web service client views.




3 Sample applications

The course administration sample applications is included in the JSlave distribution in the code/
directory. Startup scripts are provided for the Windows platform.




                                                  102
                                                                        JSlave - Hello World sample"



3.1 Hello World sample

The Hello World sample shows the basic features of JSlave and EJBs. It performs only a simple
echo operation. The actual business method is processed in a stateless bean. The business method
can be accessed over a remote interface or a web service client view.

The Hello World application shows the basic principles of stateless beans and client views.

At first the business interface is defined:

package basic.bean;

public interface BusinessInterface {
       public String businessMethod(String param1);
}


code 23: BusinessInterface.java

The Bean class implements this interface. To create a web service client view the bean class must be
annotated with @WebService and @SOAPBinding. The business method must be annotated
with @WebMethod. The values of the annotation properties are set to default.


package basic.bean;

import   javax.ejb.Stateless;
import   javax.jws.WebMethod;
import   javax.jws.WebService;
import   javax.jws.soap.SOAPBinding;


@Stateless
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class Bean implements BusinessInterface{

         @WebMethod
         public String businessMethod(String param1) {
                // This method should be executed serverside...
                System.out.println("Business Method executing. param1 is \"" + param1 + "\"");

                 // ... while the return value should be sent back to the client.
                 return "Business Method executed. param1 was \"" + param1 + "\"";
         }

}


code 24: Bean.java




                                                 103
                                                                      JSlave - Hello World sample"



The first step for a RMI client is to look up the business interface by a JNDI context. Once he has
obtained the interface he can submit calls by this interface.

package basic.client;

import basic.bean.BusinessInterface;

public class Client {
       public static void main(String[] args) throws Exception {
               javax.naming.InitialContext ic = new javax.naming.InitialContext();
                                                                                   "
               BusinessInterface businessInterface = (BusinessInterface) ic.lookup( Bean");

                                                                    "Hello World"));
                 System.out.println(businessInterface.businessMethod(
        }
}

code 25: Client.java

The JNDI properties must be set to the current JSlave settings:

java.naming.factory.initial=de.fhr.jndi.trmi.TRMIInitialContextFactory
java.naming.factory.url.pkgs=de.fhr.jndi.trmi.pkgs
java.naming.provider.url=localhost:1099

code 26: jndi.properties

The lookup of web service client views and connection by SOAP is shown in VI.4.2.2.


3.2 Course Administration Sample

The Course Administration Sample is an example bean application that is intended to show most of
the implemented features. The application represents a very easy course administration, whose main
purpose is to keep track of various professors and courses, and of which professor is taking which
course. The Professor-Course relation is therefore modeled as a 1-to-n relationship.

The Course Administration Sample is an advanced example of the features JSlave offers:

    ●   Use of legacy code

        It is possible to keep the contract between client and server free from EJB-related code. The
        functionality of a bean can be implemented by using legacy code by either delegation or
        inheritance (like implemented in EJBProfessorAdministration).

    ●   Stateless Beans



                                                 104
                                                         JSlave - Course Administration Sample"



    EJBProfessorAdministration shows the use of a stateless session bean.

●   Stateful Beans

    EJBInteractiveAdministration shows the use of a stateful session bean. Also the
    purpose        of      the      callback         listeners    is       demonstrated       (see
    EJBInteractiveAdministration.prePassivate()).

          Even though this bean seems to process data in a very old-fashioned way (text input,
          text output) it is a very realistic example. A “real” application could use this kind of
          data processing for instance to allow restricted embedded systems (like mobile
          phones) to use the beans' functionalities.

●   Web services

    EJBProfessorAdministration contains two WebMethods that are published via
    SOAP by JSlave.

●   Dependency Injection

    The Stateful Bean EJBInteractiveAdministration uses the functionality of the
    Stateless Bean EJBProfessorAdministration to maintain the professor-course
    database. The connection is made via Dependency Injection.

●   Exceptions

    An AdministrationException might be thrown by the legacy code and will be
    returned to the client. Wrong user credentials or insufficient access rights also might cause
    an Exception to be thrown by the container and delivered to the client.

●   Interceptors

    The LoggingInterceptor is an example of how an interceptor might look like. It logs
    the business method calls and the lifecycle callback calls to the console.

●   Life Cycle Callbacks




                                               105
                                                               JSlave - Course Administration Sample"



        EJBInteractiveAdministration and LoggingInterceptor contain life cycle
        callbacks that are invoked by the container.

    ●   Security

        EJBProfessorAdministration defines allowed roles for its various business
        methods. The client application passes the user credentials that the user is prompted to input
        to the server. Even though EJBInteractiveAdministration does not deny any user
        to call its methods, the called EJBProfessorAdministration methods does, and
        therefore a EJBAccessException can be thrown.


3.2.1 Client Application

The client application connects to the EJBInteractiveAdministration by using RMI. It
sends the input from the console to EJBInteractiveAdministration.proceed() and
prints out the returned value to the screen.

Actually the client application (like every client application) only needs the trmijndi.jar and
the used interfaces from the contract in its classpath. But as the client uses the
javax.ejb.EJBAccessException like defined in {server}/lib/ejb-3_0-api.jar
as well, this library has to be in the classpath, too.

The client application first asks for valid user credentials. The release version of JSlave already
contains       some        users       in       the         {server}/users.properties             and
{server}/roles.properties that can be used in the Course Administration Sample:

    ●   anonymous is the built-in anonymous user if no user credentials are passed to the server,
        but not allowed to invoke any operation of EJBProfessorAdministration.

    ●   sebastian (password: naitsabes) is in the role student and is allowed to use the
        functions (3) list Professors and (6) list Courses .




                                                      106
                                                                 JSlave - Course Administration Sample"



   ●   jobst (password: fritz) is in the role professor and is allowed to use the functions
       (7)    attach       Course       to     Professor         and (8)        detach    Course    from
       Professor additionally to those of a student.

   ●   admin (password: admin123) is allowed to perform any operation.




                       Illustration 21: Output when starting the Client as user jobst
                       and performing some operations.
After the user credentials have been entered by the user the client application establishes a RMI
connection   to JSlave. From now              on    a keyboard        command will       be sent   to the
EJBInteractiveAdministration by using its proceed() method and the return value
will be printed to the screen. By typing exit the client will leave the loop and exit.



                                                     107
                                                             JSlave - Course Administration Sample"



3.2.2 Beans

The bean sources are split into 3 packages:

   ●   de.fhr.tutorial.contract

       contains   the    interfaces   for     the   course   administration   application      plus    the
       AdministrationException class, intended to cover application specific exceptions.
       The package does not contain any EJB-related code and is the contract for the legacy
       implementation.

   ●   de.fhr.tutorial.local

       is a demonstration of how a legacy implementation could look like. It implements classes
       for the interfaces in de.fhr.tutorial.contract and stores ProfessorImpl and
       CourseImpl instances in two static Maps in a PersistenceService class. This
       package does not contain any EJB-related code either and can directly be used as a local
       version.

   ●   de.fhr.tutorial.ejb

       consists of a stateless and a stateful bean as well as one Interceptor, and in fact is the only
       package       that     contains        EJB-related      code.      The      stateless          bean
       EJBProfessorAdministration extends the legacy implementation from the
       de.fhr.tutorial.local package and implements two additional methods that have
       been added to demonstrate the call of web methods using SOAP.

       The bean EJBInteractiveAdministration is intended to show the use of a stateful
       bean. It provides a interactive administration interface by expecting input Strings and
       returning output Strings and is backed by the stateless bean.




                                                    108
                                                                       JSlave - Coding Guidelines"




4 Coding Guidelines

When writing code for the use with JSlave some aspects have to be kept in mind. In this chapter
they are described.


4.1 Coding Beans

Writing beans for JSlave is mainly the same to writing for any other EJB container. The Bean
Provider is writing POJOs that implement the business logic and packages them to EJB-Jars. Still
there are some differences:

   ●   restriction to session beans

       JSlave in its current version only supports a subset of the bean types specified in the EJB
       specification: stateful and stateless beans. Entity beans and message driven beans are not
       supported by now.

   ●   ignoring of application.xml and ejb-jar.xml

       Currently only meta data defined by using Java annotations are used within JSlave, the
       meta-inf/application.xml and meta-inf/ejb-jar.xml are completely
       ignored.

   ●   classpath

       The {server}/lib/ejb-3_0-api.jar has to be included when compiling the bean
       code. This library is part of the EJB specification and contains annotations and interfaces to
       be used in the bean code. If a stateless bean is to provide its functionality via web services,
       additionally the {server}/lib/jsr181-api.jar containing the javax.jws and
       javax.jws.soap packages is required.

Apart from these differences the coding of beans for JSlave does not differ from the coding for the
various other EJB container implementations. Usually the Bean Provider will use a build tool like




                                                109
                                                                            JSlave - Coding Beans"



Apache Ant to simplify the process of compiling, building the EJB-Jar, and deploying the EJB-Jar
or .EAR archive to the server.

        The sample applications contain Ant scripts to be used with JSlave. To make them work
        properly typically the directory paths must be adjusted according to the actual directory
        structure,

JSlave provides all libraries stored in {server}/lib for the beans during runtime. If a bean
archive needs a special library in its classpath the library has to be bundled together with the EJB-
Jar into an .EAR archive, and the manifest of the EJB-Jar must include this dependency in its
manifest.

For example, if an application.ejb would need a library.jar in its classpath during
runtime, the application.ejb/meta-inf/manifest.mf should include the following
line:
 Class-Path: library.jar


4.2 Coding Clients

Typically an EJB client needs interfaces and classes that build the common contract in its classpath.
Depending on which distribution network a client is using to connect to a deployed session bean
different aspects have to be taken into account.


4.2.1 RMI

For a RMI client the following points are important:

    ●    classpath

         The {server}/lib/trmijndi.jar has to be part of the client's classpath during
         runtime. This library provides the RMI, TRMI, and JNDI modules that are needed to use the
         RMI distribution network of JSlave.




                                                   110
                                                                            JSlave - Coding Clients"



             Note, that the rest of the libraries in {server}/lib are not needed for the client as
             long as there are no other dependencies. Usually there will be further dependencies,
             at least to the remote interfaces a bean offers.

   ●   jndi.properties

       The easiest way to configure JNDI to connect to JSlave is by using a jndi.properties
       that has to be within the classpath of the client. The following values have to be specified:

       ○   java.naming.factory.initial=de.fhr.jndi.trmi.TRMIInitialCon
           textFactory                                                                             and
           java.naming.factory.url.pkgs=de.fhr.jndi.trmi.pkgs

           This property configures JNDI to use the TRMI system.

       ○   java.naming.provider.url=localhost:1099

           This property is a URL pointing to the RMI port of a running JSlave instance.

       ○   java.naming.security.principal=username                                                 and
           java.naming.security.credentials=password (optional)

           By setting these properties the JNDI extension module uses the authentication
           mechanism (like defined in IV.5.1.4) and passes the username and password to
           JSlave.

   ●   Lookup

       The following lines of code can then be used to get a stub of a bean that implements a
       IBusiness interface:
InitialContext ic = new InitialContext(environment);
IBusiness stub = (IBusiness) ic.lookup("BusinessBean");


4.2.2 Web Services

This chapter covers only the use of a bean via JAX-WS RI, as due to the diversity of different web
service frameworks, platforms, and programming languages there is a enormous amount of




                                                 111
                                                                            JSlave - Coding Clients"



considerations to be taken into account. Especially the use of user credentials might be different in
other frameworks.

To use the web methods of a bean via JAX-WS RI the following steps have to be done:

   ●   Import of the WSDL

       The    WSDL     description   of   a   bean    called   BeansName       is   published   under
       http://localhost:8080/BeansName?wsdl (if JSlave runs at the same host and
       uses the standard configuration). To use it by JAX-WS RI the wsimport has to be
       executed like this:
wsimport -keep http://localhost:8080/BeansName?wsdl


   ●   Classpath

       To make JAX-WS RI available in the client its classpath has to include all libraries in
       {server}/lib, which are mainly JAX-WS libraries.

   ●   Lookup

       To get a SOAP connection to a bean BeansName the following lines of code are required:
BeansNameProxyService beansNameService = new BeansNameProxyService();
BeansName beansName = beansNameService.getBeansNamePort();


   ●   Authentication (optional)

       If the client wants to pass user credentials to JSlave the following lines have to be appended:
BindingProvider bindingProvider = (BindingProvider) beansName;
                                                       USERNAME_PROPERTY, "username");
bindingProvider.getRequestContext().put(BindingProvider.
                                                       PASSWORD_PROPERTY, "password");
bindingProvider.getRequestContext().put(BindingProvider.




                                                112
                                                                                  JSlave - Limitations"




VII Limitations
The purpose of this chapter is to mention some of the limitations the JSlave in its current version
has. As JSlave is only a partial implementation of the EJB specification and not intended to be used
within a production environment, there are a lot of deviations from the EJB specification. The most
important of them - besides the lack of persistence, transactions, asynchronous beans, and so on –
are named here.


1 Backwards Compatibility

According to the specification a EJB 3.0 Container has to be backwards compatible to EJB 2.1 and
partially to EJB 1.1. Different client views, life cycle callbacks, and many small differences in detail
are needed to support the backwards compatibility.

JSlave does not provide these differences at all, nor implements a structure that could be used to
easily extend the current version by this behavior. Instead, JSlave is implemented as a version 3.0
EJB container only.


2 Dependability

A container must be robust against situations that could cause a invalid state of the bean instances or
a crash of the application server. These situations include (but are not restricted to)

   ●   violations of the session bean contract

       The EJB specification covers dozens of situations where a bean can violate the session bean
       contract (e.g. wrong method signature of life cycle callback listeners, illegal conversational
       state after the prePassivate() callback, etc.).

   ●   system errors and exceptions




                                                  113
                                                                             JSlave - Dependability"



       Exceptions that can occur in the JVM of the container (e.g. IOException,
       OutOfMemoryException)

   ●   shared memory access

       Intentional and unintentional access from a bean to the memory of another bean or the
       container classes

All these cases must be treated in a certain way to avoid a container crash and to allow
dependability. The EJB specification describes how to handle situations like these in detail.

JSlave is not intended to be used in a production environment; its behavior in exceptional situations
has not been tested and will likely end up in an illegal state of the container, the beans, and/or the
client applications.


3 Infrastructure Integration

The Java Enterprise Edition specifies technologies and systems to be used within an enterprise
environment, usually consisting of an existing infrastructure and containing database servers,
directory servers, interfaces to enterprise information systems, and so on. A container
implementation based on the EJB specification thus must be integrated into the existing enterprise
environment rather than requiring a company to replace the whole infrastructure at once.

The Java Enterprise Edition therefore defines technologies and interfaces to enable the various
systems to collaborate. Besides the Connector API there are some more interactions mentioned in
the EJB specification to allow application servers to work together:

   ●   Remote Invocation Interoperability (see [ejbspec] 15.5)

   ●   Transaction Interoperability (see [ejbspec] 15.6)

   ●   Naming Interoperability (see [ejbspec] 15.7)

   ●   Security Interoperability (see [ejbspec] 15.8)




                                                 114
                                                               JSlave - Infrastructure Integration"



JSlave does not implement any of the specified interoperability aspects but is more or less a stand-
alone system; connections to external systems are only provided by using the distribution subsystem
for the deployed session beans and via JMX.


4 Scalability and Workload Balancing

Aside from the necessity to integrate seamless into a existing server infrastructure an enterprise
system must be able to meet a varying amount of requests per time interval. This can be provided
by using application servers and EJB containers that are scalable and use workload balancing to
route requests to servers with available resources.

Scalability was not a requirement for JSlave and thus has not been implemented. Technically
possible would be some sort of cluster support within the container, so that bean instances are
created on different nodes of a cluster. The BeanExecutionManager and the BeanInstance
instances therefore would have to extend the current functionality by workload balancing and
remote execution, respectively.


5 Incompleteness

Most features of JSlave are incomplete or erroneous according to the EJB specification. This is due
to the fact that JSlave shall show how a EJB container could work like in principle rather than to be
a 100% implementation of the EJB specification. Some important (but by far not all) deviations are
mentioned in this chapter.


5.1 Meta Data

When collecting information for the deployment of beans an EJB container usually is responsible
for parsing information from different sources: the Java Annotations, the application.xml of a
.EAR archive, the ejb-jar.xml from an EJB-Jar, and from different deployment tools that are
container-specific. The information must be merged according to different rules that are described
in the EJB specification.




                                                 115
                                                                                 JSlave - Meta Data"



JSlave in the current version only uses information coming from the Java Annotations, information
from the other sources are completely ignored. Further only some of the annotations are getting
processed, some only at particular points, and some only partially (by ignoring some parameters).


5.2 SessionContext

The SessionContext interface represents the only way for a bean to communicate actively with
the container and can be obtained by either using JNDI lookup or Dependency Injection. A
complete description of the SessionContext interface can be found at [ejbspec], 4.3.3.

The current SessionContextImpl class in JSlave does only implement the following methods
properly: getCallerPrincipal(), isCallerInRole(), and lookup(). All the other
methods either throw an exception or return potentially invalid results.


5.3 TimerService

The EJB specification requires a container to implement a TimerService to be used for time-
based notification of bean instances.

Although a TimerServiceImpl is incorporated in JSlave it is not implemented at all but
contains only method stubs returning standard values. Further, the timeout callback methods for
stateless session beans are not implemented like described in [ejbspec] 4.3.8.




                                                 116
                                                                   JSlave - Bibliography"




VIII Bibliography
ejbspec: EJB 3.0 Expert Group, JSR 220: Enterprise JavaBeans, 2006,
Sun01: Sun Microsystems, Your first cup: An Introduction to the Java EE Platform, 2006
Sun02: Sun Microsystems, The JavaEE Tutorial, 2006
rmispec: Sun Microsystems, Java RemoteMethodInvocation Specification, 2004
JSR181: Java Community Process(JCP), Web Services Metadata for the JavaTM
Platform, 2005
FKRbac: D.F. Ferraiolo and D.R. Kuhn, "Role Based Access Control", 1992
rfc2617: The Internet Society, RFC 2617, 1999, http://tools.ietf.org/html/rfc2617




                                          117
A.Illustrations

Illustration 1: Java Enterprise Edition overview.....................................................................6
Illustration 2: A client performs calls on the CartBean session bean over the Cart interface.
The CartBean is located in the container. [ejbspec], 46......................................................11
Illustration 3: Life cycle of a stateful session bean[Sun02], p642........................................14
Illustration 4: Life cycle of a stateful session bean[Sun02], p642........................................14
Illustration 5: Structure of an EAR file([Sun02], p53)...........................................................17
Illustration 6: Structure of an EJB-JAR, ([Sun02], p641).....................................................17
Illustration 7: Web service client views of stateless session beans([ejbspec], p49)............27
Illustration 8: UML diagram base classes............................................................................40
Illustration 9: UML diagram basic connection and bean classes.........................................42
Illustration 10: In the current version of JSlave each enterprise bean archive will have a
superordinate ClassLoader for the whole archive, and one more more subordinate
ClassLoaders for each EJB-Jar...........................................................................................49
Illustration 11: UML diagram meta data...............................................................................51
Illustration 12: UML diagram Proxy generation....................................................................56
Illustration 13: Connections resulting from a RMI call of EJBInteractiveAdministration......60
Illustration 14: UML Diagram bean instances......................................................................62
Illustration 15: Passivation of a stateful bean BeanImpl......................................................67
Illustration 16: Invocation of the BeanClass.method() while using the two interceptors.....72
Illustration 17: Call stack resulting from RMI and TRMI......................................................76
Illustration 18: UML diagram web services..........................................................................79
Illustration 19: UML diagram user management..................................................................81
Illustration 20: Different threads and some of the container's data structures....................83
Illustration 21: Output when starting the Client as user jobst and performing some
                                                                                               .
operations...................................................................................... ...................................107
B.Supported Annotations

The following Java Annotations are supported by JSlave:

Annotation                  Limitations
@AroundInvoke               only supported in interceptor classes, not in the bean class itself
@DenyAll
@EJB
@EJBs
@Interceptors               ignored for the superclass of a bean class and on method-level
@Local
@PermitAll
@PostActivate               only supported for the bean and interceptor class, respectively;
                            external callback listeners are ignored
@PostConstruct              only supported for the bean and interceptor class, respectively;
                            external callback listeners are ignored
@PreDestroy                 only supported for the bean and interceptor class, respectively;
                            external callback listeners are ignored
@PrePassivate               only supported for the bean and interceptor class, respectively;
                            external callback listeners are ignored
@Remote                     supported completely, but implicit remote interfaces (a bean class
                            implementing exactly one interface) are ignored
@Resource                   only useful for SessionContext, as the values cannot be set using
                            the Deployment Descriptors
@Resources                  only useful for SessionContext, as the values cannot be set using
                            the Deployment Descriptors
@RolesAllowed
@RunAs
@Stateful                   parameters description and mappedName are ignored
@Stateless                  parameters description and mappedName are ignored
                                Erklärung zur Aufgabenteilung



Hiermit wird die Aufgabenteilung bei der Erstellung der Diplomarbeit “Development of a JEE
Application Container for Session Beans” bestätigt.

Sebastian Vogel hat folgende Kapitel erstellt:

IV.2.1 ClassLoader Delegation Hierarchy

IV.2.2 Meta Data Processing

IV.2.3 Bean Environment

IV.3 Connection management

IV.4 Life Cycle of a Session Bean Instance

IV.5 Distribution subsystem

IV.6 Security Subsystem

IV.7 Multithreading

V.1 Bean Environment Multiplexing

V.3 RMI limitations

V.4 Authentication

VI.3.2 Course Administration Sample

VI.4 Coding Guidelines

VII. Limitations




Rainer Garhammer hat folgende Kapitel erstellt:

I. Abstract

II. Enterprise Java Beans 3.0

III. Requirements for JSlave
IV.1 Structure

IV.8 Monitoring and Logging

V.2 Code generation

VI.1 Installation

VI.2 Server

VI.3.1. Hello World sample




Regensburg d. 12.03.2008




Sebastian Vogel               Rainer Garhammer
                                      ERKLÄRUNG



   1. Mir ist bekannt, dass dieses Exemplar der Diplomarbeit als Prüfungsleistung in das
      Eigentum des Freistaates Bayern übergeht.
   2. Ich erkläre hiermit, dass ich diese Diplomarbeit selbständig verfasst, noch nicht anderweitig
      für andere Prüfungszwecke vorgelegt, keine anderen als die angegebenen Quellen und
      Hilfsmittel benützt sowie wörtlich und sinngemäße Zitate als solche gekennzeichnet habe.




Regensburg d. 12.03.2008




Sebastian Vogel
                                      ERKLÄRUNG



   3. Mir ist bekannt, dass dieses Exemplar der Diplomarbeit als Prüfungsleistung in das
      Eigentum des Freistaates Bayern übergeht.
   4. Ich erkläre hiermit, dass ich diese Diplomarbeit selbständig verfasst, noch nicht anderweitig
      für andere Prüfungszwecke vorgelegt, keine anderen als die angegebenen Quellen und
      Hilfsmittel benützt sowie wörtlich und sinngemäße Zitate als solche gekennzeichnet habe.




Regensburg d. 12.03.2008




Rainer Garhammer

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:21
posted:11/9/2011
language:English
pages:123