3. 1. Introduction
Java EE platform provides a mature environment for deploying enterprise components
that are managed by the application server. The application is responsible for providing
those components with common requirements needed in most enterprise applications. We
are going to discuss some of the services provided by a typical Java EE applicaiton server.
2. Resource Management
Resource management is the primary responsibility of the application server. It can
manage thousands (and even millions) of objects and components without a great
requirement of memory space! This is implemented by the application server using two main
techniques:
2.1. Resource Pooling
Resource pooling is a technique used to manage non client-specific components. A resource
pool is a collection of many identical instances of the same class. When a client requests a
reference to a component of a specific type, the application server returns a reference to
any free component from its resource pool. The instance is reserved to the client as long
as it uses it. Other clients will not get a reference to this instance and will get a reference
to other instances from the instance pool until it get released. This technique can satisfies
dozens of users simultaneously using a smaller number of instances, depending on the
low probability of actual concurrent usage. If actual concurrent usage exceeded available
instances, more instances are created and added to the pool, depending on the application
server's implementation behavior. Stateless-session beans, message-driven beans, and data
sources are managed using resource pooling technique.
2.2. Activation/Deactivation Mechanism
Activation/Deactivation mechanism is a technique used to manage client-specific
components. When a client requests a reference to a component of a specific type, the
application server instantiates an object from the class and returns its reference to the
client. The component is active in memory as long as the client actually uses it. If the client
stopped using the component for a long period of time, the application server deactivates the
component by serializing it in some persistent storage. Once the client get back using the
component, the application server activates the component again by deserializing it again to
the memory from the persistent storage and makes it active to resume interacting with the
client.
3. Java Naming and Directory Service
Resource naming is another primary responsibility of the application server. It provides an
implementation to the Java Naming and Directory Service specification by Sun Microsystem,
which is a system of a logical repository of names associated with references to different
resources. Clients can access the service using the Java Naming and Directory Interface APIs
(JNDI).
3
4. 4. Security Services2
Security is a primary requirement in any application. It's another responsibility of the
application server. Java EE uses declarative security model that can be used with Java EE
components using some configurations.
4.1. Declarative Security
Declarative security model introduces the concept of roles. A role is an abstract class of users.
Users can be defined and associated with specific roles declaratively using configuraiton files.
Services in Java EE components can be declared to be accessible only for some roles. Users
should login first before using secured services. The following sections show how can we use
security services using JBoss application server for both, business and web components.
4.1. Defining a Security Domain
A security domain is a collection of security configurations assigned a specific name. Security
domains can be defined by adding XML elements to the
file C:jbossserverdefaultconflogin.config.xml as follows:
file: C:jbossserverdefaultconflogin.config.xml
...
<application-policy name ="foo">
<authentication>
<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
flag="required">
<module-option name="usersProperties">
props/foo-users.properties
</module-option>
<module-option name="rolesProperties">
props/foo-roles.properties
</module-option>
</login-module>
</authentication>
</application-policy>
...
</policy>
Users are defined in C:jbossserverdefaultconfpropsfoo-users.properties. It's a
user per-line file. Each line consist of the username followed by = and its password.
2. All written examples use JBoss-specific features.
4
5. file: C:jbossserverdefaultconfpropsfoo-users.properties
abdalla=abdallapass
ahmed=ahmedpass
Roles are defined in C:jbossserverdefaultconfpropsfoo-roles.properties. It's a
user/role per-line file. Each line consist of the username followed by = and its associated
roles.
file: C:jbossserverdefaultconfpropsfoo-roles.properties
abdalla=admin
ahmed=employee
4.2.1. Business Components
Securing a business component is simple and straightforward. Here is a sample business
component before and after securing:
Before Securing
file: mypackMyEJB.java
package mypack ;
import javax.ejb.* ;
@Stateless
public class MyEJB implements MyEJBRemote {
public void foo() {
System.out.println("foo() invoked.") ;
}
public void protectedMethod() {
System.out.prtinln("protectedMethod() invoked!") ;
}
public void protectedMethod2() {
System.out.prtinln("protectedMethod() invoked!") ;
}
}
After Securing
file: mypackMyEJB.java
package mypack ;
5
6. import javax.ejb.* ;
import javax.annotation.security.* ;
import org.jboss.ejb3.annotation.SecurityDomain;
@Stateless
@SecurityDomain ("foo")
public class MyEJB implements MyEJBRemote {
public void foo() {
System.out.println("foo() invoked.") ;
}
@RolesAllowed({"admin"})
public void protectedAdmin() {
System.out.prtinln("protectedAdmin() invoked!") ;
}
@RolesAllowed({"employee"})
public void protectedEmployee() {
System.out.prtinln("protectedEmployee() invoked!") ;
}
}
Remote clients should login first before using the component, as follows:
file: Client.java
import javax.naming.* ;
import mypack.MyEJBRemote ;
import org.jboss.security.client.* ;
public class Client {
public static void main(String[] args) throws Exception{
SecurityClient client = SecurityClientFactory.getSecurityClient();
client.setSimple("abdalla", "abdallapass");
client.login();
InitialContext ctx = new InitialContext() ;
MyEJBRemote r = (MyEJBRemote) ctx.lookup("MyEJB/remote") ;
r.doAdmin() ;
}
}
6
7. 4.2.2. Web Components
Securing web components requires a login and error page, with additional declarations
in the web.xml file. Here is a sample web application of two web components
(protectedPage1.jsp, protectedPage2.jsp) before and after securing:
4.2.2.1. Login Page
file: login.html
<html>
<head>
<title>Login Page</title>
</head>
<body>
<font size='5' color='blue'>Please Login</font><hr>
<form action='j_security_check' method='post'>
Name: <input type='text' name='j_username'>
Password: <input type='password' name='j_password' size='8'/>
<input type='submit' value='login'>
</form>
</body>
</html>
4.2.2.2. Error Page
file: error.html
<html>
<head>
<title>Error!</title>
</head>
<body>
<font size='4' color='red'>
The username and password you supplied are not valid.
</font>
Click <a href='/webapp/login.html'>here</a> to retry login.
</body>
</html>
7
8. 4.2.2.3. Deployment Descriptor
file: WEB-INFweb.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/
xml/ns/javaee/web-app_2_5.xsd">
<!-- Defines a security constraint element -->
<security-constraint>
<web-resource-collection>
<web-resource-name>A Protected Page</web-resource-name>
<url-pattern>/protected-page.jsp</url-pattern>
<url-pattern>/protected-page2.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<!-- Defines the login mechanism -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
</web-app>
4.2.2.4. JBoss-Specific Deployment Descriptor
The JBoss-specific deployment descriptor is used to specify's JBoss-specific configurations
for the web applicaiton. It's located in WEB-INF/jboss-web.xml. We will add this file to
declare the security domain associated with this web applicaiton.
8
9. file: WEB-INF/jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>java:/jaas/foo</security-domain>
</jboss-web>
5. Transaction Service
Transactions are required in most enterprise applications. A transaction is an atomic
operation that should be performed completely. Some operations may fail to complete for
some reasons, most common is exceptions. Operation may have affected state before the
exception occurs, which puts the system in an illegal state. The solution is to undo all
changes made in the period between starting the operation and the exception occurrence.
Fortunately, all business operations are invoked within the scope of a transaction initiated by
the application server. If the invocation could not be completed for a reason or another, all
state manipulations will be rolled back.
9