Logo ©1994-2007 Kevin Boone
My professional interests
Computing
Law
Education
Science and research

My leisure interests
Martial arts
Heritage railways
Garden railways
Motorcycles
DIY

Downloads
Linux downloads
Windows downloads
Java downloads
Perl downloads
Home automation downloads

About me
Home & family
My CV

Site info
Contact the author
Download policy
Keyword index

  Home > Computing > Sofware development

A SunONE Application Server 7 FAQ

Last modified: Fri Aug 3 08:54:07 2007

[Update 08/07: this document is completely obsolete!]

Disclaimer

The author is a certified iPlanet/SunONE instructor, but not involved in any way with the development or management of the SunONE product line. Please bear in mind that the following notes are based on my own experiences, and those of other people working with SunONE Application Server in the field. They do not constitute official pronouncements from Sun Microsystems. Statements like `...has been found to work in practice' mean exactly that: at least one person has reported success. They should not be taken as a recommendation to follow a particular course of action.

What versions of the application server are available?

SunONE Application Server 7 has two basic versions: a Platform Edition, which is supplied as part of modern Solaris releases and is free-of-charge for development and production, and a Standard Edition, which is free-of-charge for development and evaluation. For production use, the Standard Edition costs about $2000 per CPU. The most obvious difference between the Platform Edition and the Standard Edition is that the former has no support for remote administration. You have to have console access to administer it.
      At the time of writing (June 2003), the Enterprise Edition, which will provide full failover and load balancing support, was not available for general release.
      The Standard Edition is also available bundled with the SunONE Studio IDE tool, version 5. Integration between the IDE and the application server is now very slick, and well worth investigating.

Is there a Linux version?

Yes. Administration is almost identical to the Solaris version.

Is there a Windows version?

Yes, but I haven't used it so I can't really comment on it.

How is SunONE Application Server 7 different from iAS 6/6.5?

In every conceivable way. S1AS7 is, in effect, a completely new product, and has little, if any, version 6 code in it. S1AS7 shares code with the J2EE Reference Implementation, Tomcat, SunONE Message Queue, Forte Transparent Persistence, and the SunONE Web Server, version 6.

What is the application server's basic architecture?

The application server services web clients using the HTTP core from the SunONE Web Server, version 6. This core is written in C, and supports all the usual web server features, such as CGI, static content, quality of service definitions, and virtual servers. In addition, on Solaris platforms the HTTP core can integrate with the kernel-level HTTP cache.
      If an incoming HTTP request is not for an item of static content, but corresponds to a web application, then the request is routed to a J2EE plug-in module based on the proprietary NSAPI interface. This module is also written in C. The plug-in passes the request to an embedded JVM, which is running a variant of the Tomcat servlet/JSP engine. The JVM also runs the EJB core and the various back-end services, such as connection pooling, resource adapters, and persistence management.
      The EJB core is also accessible to IIOP clients, which might be stand-alone Java applications, or applications written in other languages.
      Supplied with the application server is a variant on the SunONE Message Queue (formerly iPlanet Message Queue) which can be used to support applications that use asynchronous messaging. Note that this is not related in any way to the SunONE Messaging Server, which is an e-mail server.

What are domains, instances, and virtual servers?

A S1AS7 installation is structured heirarchically, with the domain being the top level of the hierarchy. Domains are, to all practical intents and purposes, different installations of the server (except that the installations share a common set of binaries). Each domain has its own administration server with its own admininstrator credentials and administration port number.
      Within each domain there are any number of instances. In practice there must be at least two -- the administration server instances and one working instance. Applications and content are deployed on the working instances, while the administration server instance supports the administration console.
      Each instance has its own HTTP listener configuration, so different IP numbers of ports can be handled by instances. Each instance, including the administration server instance, has its own set of three appservd processes.
      Each instance has at least one virtual server. When the instance is created, by default it gets one virtual server with the same name as the instance. Virtual servers, which can be IP-based or host-based (see below). Virtual servers appear to clients to be independent web servers, but in fact they are only different configurations of a particular instance. Each virtual server has its own quality of service configuration. For example, different virtual servers can have different bandwidth limits.
      Also associated with each instance are one or more HTTP listeners. A listener runs in one or more threads (selectable in the administration console), and accepts incoming HTTP connections. A listener listens either on a single IP number, or any IP number. In either case, the listener binds to a single port number. The default is for a listener to accept requests on any IP number.
      Each listener feeds incoming requests to one or more virtual servers. Each virtual server that is attached to a listener has the opportunity to handle the request. If no virtual server handles the request, then it is passed to the listener's default virtual server. Typically the default virtual server is the one that was created first, and has the same name as the instance. Where a listener is feeding requests to more than one virtual server, typically the virtual servers will be configured to accept requests when the host name supplied by the browser matches some pattern. For example, suppose we have a server with a single IP number (say 100.101.102.103), which corresponds to two DNS names -- fred.acme.com and bill.acme.com. We want requests to fred.acme.com to go to a virtual server called `fred', while requests for bill.acme.com go to virtual server `bill'. Because there is only one IP number, there can only usefully be one HTTP listener. The virtual servers fred and bill will both be assigned to this listener. However, one of the instances has to be the default, for requests that don't correspond to either fred.acme.com or bill.acme.com.

To support multiple host names on the same physical host, should I use different virtual servers or different instances?

Either will work. If you have a small number of hostnames, then assigning different instances gives a finer degree of control. This is only possible if the host names map onto different IP numbers. Where there is only one IP number, or where there are many hostnames to support, it is much more efficient to use virtual servers.

How do I stop and start the application server?

As each instance of the application server is a daemon process in its own right (actually, it's three daemons), it is instances that are stopped and started, rather than the server as a whole. However, it is possible to stop or start all instances in one operation, which is equivalent to stopping or starting the entire server.
      There are two basic methods: use the asadmin utility, or start the admin server and instances by running their daemons explicitly.

To start all instances using asadmin:

asadmin start-appserv
To start all instances in domain `domain1':
asadmin start-domain --domain domain1
To start instance `instance1' in domain `domain1':
asadmin start-instance --domain domain1 instance1
To stop, just replace the word `start' with `stop'.

To start and stop the daemons explicitly, find the bin directory of the instance, then run `startserv' or `stopserv'. For example:

cd /var/appserver/domains/domain1/instance1/bin
./startserv

Which operating system processes are associated with the application server?

For each instance of the application server you should see the following processes.
  • appservd -- two processes per server instance (see below for why). These processes handle all incoming HTTP and IIOP requests
  • appservd-wdog -- starts the other processes, and restarts them if they shut down unexpectedly
  • imqbrokerd -- a shell script or batch file that starts, and acts as a watchdog for, the IMQ message broker, which is a Java application
  • IMQ message broker -- appears as a java process

Why are there two appservd daemons for each server instance (unix platforms) ?

These are the primordial and worker daemons. It is anticipated that in future releases of the product, each instance will support multiple worker processes, with the primordial balancing load between the workers. At present, the primordial process has no particular function.

Where are the configuration files?

Configuration files operate at an instance level, and are found in the config directory of a particular instance. The important ones are as follows.
  • init.conf -- specifies minimal instance-level configuration, such as the account that will own the application server processes. This file also contains the NSAPI commands to load the plug-in module that connects the web server core to the application server, and to intialize it. There are few good reasons to edit this file, and it is not modified by the administration server
  • obj.conf -- configuration for plug-in modules, including the J2EE connector plug-in. As with init.conf, there are few good reasons to edit this file
  • server.xml -- main configuration file for the application server and web server cores. Contains configuration for the HTTP listeners, IIOP listeners, virtual servers, security, etc., etc. Most changes made by the administration console or the asadmin command modify server.xml. If you modify it by hand, you will need to restart the instance for the changes to take effect.
  • keyfile -- user IDs, groups, and passwords, for users whose credentials are stored in the `file realm' security realm (see below).
  • login.conf -- provides a list of Java classes that implement the authentication methods the application server supports.
  • mime.types -- maps file extensions onto MIME data types. This file is only relevant to the processing of static HTML pages.

What are security realms?

A security realm is a particular method for authenticating users and assigning them to groups. Another way of expressing this concept is that a realm is a set of users who authenticate against a particular authentication repository (see next question).

What authentication repositories are supported?

As delivered, the application server supports unix authentication, LDAP authentication, and text files. Unix authentication simply passes an authentication request to the underlying operating system, so any Unix PAM modules will be invoked as for a Unix log-in. LDAP authentication operates against a directory server. Text file authentication works against a text file containing user IDs and encrypted passwords. The administrator can manage this file using the administration console.
      Because the application server supports JAAS (Java Authentication and Authorization Service), you can plug in any JAAS-compliant authentication module, or write your own. Alternatively, you could use one of the many JAAS modules that already exist. For example, a JAAS module for authenticating to a database table is available as part of the Jakarta project.

Where are kregedit, etc

Gone, thankfully. iAS6 provided a `registry viewer' to manipulate the configuration registry product, to achieve tasks that could not be carried out using the graphical administration console. This version of the application server has no equivalent of kregedit for two reasons. First, it keeps all its configuration in files in the config directory, and if you want fine control you can edit them using a text editor, or programmatically. Second, most configuration that you'll need to do can be done using the graphical console. If you want to change configuration settings in a script, and don't want to manipulate server.xml directly, the you could use the asadmin set command, which can set any configuration property.

Where are the log files

By default, logs are collected for each instance. All virtual servers show their logging information in the same log. This behaviour can be changed by specifying new log file locations in the administration console. Otherwise, the logs are in [instance_directory]/logs. The file access records requests made on the HTTP core. The file server.log records messages from the application server.

Can the application server log to the Unix system log?

Yes, but it is not enabled by default. This facility can be managed through the administration console.

Can the logging granularity be changed?

Yes, both for an instance as a whole and for the individual services within it. At the instance level, log granularity can be set to one of nine levels, from `info' (a great deal of logging) to `fatal' (only logs crashes). In each subsystem you can set the log level to one of these nine levels, or you can set it to `Default', so it takes the default value for the instance.

How can I view the logs?

The logs are only text files. You can view them with a text editor. If you cannot log in to your server and get a prompt (a wise precaution), you can view the logs through the administration console.

Are the logs buffered?

This may be important because on a very busy system the access log will grow very quickly, and writing the log to file is a significant overhead. By default, the access log is kept in memory and flushed every 30 seconds. server.log does not appear to be buffered for such a long period, but the amount of data delivered to this file should, in normal operation, be small.

Does the application server support log rotation?

Yes, but the settings page in the administration consoles is easy to miss, because the link for it appears below the tabs. Select the required server instance then click the `Logging' tab. The link for `Log Rotation' is below the tabs, but you may have to scroll the tab pane to get to it.
      There are two built in methods of log rotation. `Internal' log rotation is carried out by the appservd process itself, while `scheduler-based' rotation is done by a separate process called schedulerd. The documentation talks about a `cron' process, but schedulerd is unconnected with the standard unix cron utility.
      The application server will also coexist with system-based rotation utilities like newsyslog (Solaris) and logrotate (Linux).

Does the application server support load balancing?

The Standard Edition does not support load balancing, at least not in a way that is supported. However, the application server is supplied with a reverse proxy plug-in called libpassthrough.so (passthrough.dll on Windows systems) which has rudimentary load sharing facilities. In particular, it can do simple round-robin distribution of requests, with session affinity at the IP level. IP-level session affinity means subsequent requests from clients with the same IP number go to the same server in the group. This avoid the problem of breaking up session data between the servers, but is less flexible that session affinity that works at the HTTP protocol level.
      libpassthrough.so is rather fiddly to configure because, although it is documented, the documentation assumes that you understand NSAPI configuration in general. If you don't, you might find it helpful to have a skim through the NSAPI reference manual first.

What is the difference between a `DataSource' (or data source) and a `connection pool'?

A connection pool is named set of physical connections to a particular external resource, that can be shared between different users. Each connection in a particular connection pool connects to the resource using the same user credentials. The `name' assigned to the connection pool is registered with the application server's naming service, and typically takes the form `jdbc/XXX' when the external resource is a relational database.
      A DataSource is a named connection to an external resource that may, or may not, be pooled. Again, the name is assigned to the naming service, and has the form `jdbc/XXX'.
      In normal operation, an application server connects to an external resource using a named DataSource, not a connection pool. A single connection pool may be shared between different DataSources. So, setting up the application server to allow applications to connect to an external resource has two steps:
  • Create a connection pool
  • Create a DataSource with the newly created connection pool as its allocated connection pool
This two-stage approach gives significantly increased flexibility, because other parts of the application server (e.g., the persistence manager) can use the connection pool via its registered name, without needing to go through a DataSource. At the same time, have applications use the DataSource name decouples them from the internal pooling system of the application server.

There is one complication with all this. I said that a DataSource is a named connection to an external resource that may, or may not, be pooled. The problem is that the connection pool itself needs some way to connect to the external resource. It does this by using a DataSource! This sounds like a circular argument, but in fact there are two different DataSources at work here. The application server's connection pool connects to an external resouce using a DataSource supplied by the resource vendor, then the application server offers its own DataSource to the application. The chain of communication from the application to the external resource thus looks like this:

      application 
          |
          |
          V
 app. server's DataSource
          |
          |
          V
app. server's connection pool
          |
          |
          V
 resource vendor's DataSource 
          |
          |
          V
   resource vendor's drivers
          |
          |
          V
    external resource 

What database engine is the application server supplied with?

The distribution versions of the application server are supplied with a limited version of the PointBase relational database. The Platform Edition that comes with Solaris 9 is not, but PointBase is available as part of the Solaris 9 distribution and can be installed separately (package name SUNWasdbo). The problem with this latter approach is that the JAR file containing the driver does not end up on the application server's class search path. You need to find pbclient42RE.jar and copy it to the application server's lib directory.

How do I enable SSL for the application server?

SSL is enabled for specific HTTP listeners, not for server instances or virtual servers (except for the administration server -- see below). So if you want to enable SSL for a specific virtual server, you must find the HTTP listener that is servicing that virtual server. In most cases this is straightforward, because there will be one virtual server per listener. However, if you are using host-based virtual servers, you may have a complex mapping between listeners and virtual servers. In any case, you can find the properties page for the virtual server in the administration console, and it should show which listener(s) are servicing the server.
      In the configuration page in the appropriate HTTP listener, check the box that says `SSL/TSL enabled'. You may want to review the cipher settings; by defualt 40-bit ciphers are disabled. Then you'll need to select a certificate to use. Certificates are selected using the `Certificate Nickname' list, where the nicknames are the names you assigned when you installed the certificates. It is at this stage that administrators typically realise that they don't know how to get or install a certificate (see next question).

How do I install a server certificate?

I assume (for now) that you want to install a certificate that has been validated by a commercial or organizational certificate authority (CA) (if not, see next question). There are three steps to the process: (1) generate a certificate signing request (CSR); (2) send the CSR to the CA to be signed; (3) get the signed certificate back; (4) install the signed certificate. All these steps can be accomplished using the administration console, in the `Certificate Management' page for a particular server instance. To get this page, select the `Security' node in the console, then the `Certificate Management' tab. Under the list of tabs (and therefore difficult to see) are three links: `Request', `Install', and `Manage'. Use the `Request' page to generate a CSR, and the `Install' page to install the signed certificate when you get it back. It's as simple as that.
      Before you can do any of the steps described above, you'll need to initialize the keystore database (there is a tab labelled `Manage Database' for this). Bear in mind that the keystore database is password protected. On the Manage Database page the password is referred to as the `database password', but on all the other administration pages it is referred to as the `key pair file password'. These are the same password; this is just to keep you on your toes. All changes to the certificate database require a server restart, and once you have created a keystore database you'll have to enter the keystore database password every time you start up the server.
      The administration console gives the option of e-mailing the CSR to the CA, or invoking a URL to send the CSR. What happens if your server doesn't have internet access? In a production environment it is most likely that it won't have. When the console generates a CSR to send by e-mail, it also writes it to a file in the /tmp directory, so you can just enter a bogus e-mail and then capture the file for later processing.

Can I use a non-CA certificate for development/evaluation?

There might be occasions on which you want to enable SSL for a server, but don't want to go through the hassle of generating a CSR and having it signed by a CA. In a development system, for example, and quite possibly for the administration console itself, you won't need a signed certificate. However, to the best of my knowledge (and I've searched really hard), there is no way to drop a self-signed certificate into the certificate database, and use that as the server certificate. The reason for this is that the administration console expects the server certificate to come back from the CA encrypted using the certificate's public key, and then to have to decrypt it using the certificate's private key. The private key was stored during the generation of the CSR. So if the administration console is given a server certificate that is not encrypted, it won't install it. If it is encrypted, then it won't be able to decrypt it because it doesn't have the matching private key available.
      Now, you can install a self-signed certificate as a CA certificate, rather than a server certificate, without its needing to be encrypted (obviously -- you've won't have the CA's private key to decrypt it with). However, the application server refuses to use what it believes is a CA certificate as the server certificate. This appears to be an aribtrary design decision: there is no cryptographic reason why the server can't offer a self-signed certificate as part of the SSL handshake. Most other web servers allow self-signed certificates to be used.
      Anyway, the long and short of it is that you will need to generate a CSR and have it signed to get SSL working on the application server. The server does not care who signs the certificate -- it can be any self-signed certificate -- but it requires that the certificate has been through the CSR process. You can use a commercial CA product, such as SunONE Certificate Manager, to sign your CSRs. Alternatively, you can use OpenSSL, which is free of charge.
      The following is a detailed description of how to use OpenSSL and the application server administration console to generate a CSR, send it to the CA (you, in this case), sign it, send the signed certificate back, and install it. You can get a Solaris version of OpenSSL from sunfreeware.com. If you don't have GCC installed, you'll need to get libgcc-3.3 as well, from the same place. It speeds things up enormously if you can get a copy of the script sign.sh, which is part of the Apache mod-ssl distribution. This script automates the creation of the large number of files and command-line arguments you need to use OpenSSL to sign a CSR.

Step 1 - generate the self-signed certificate using OpenSSL

In the following, I assume that the openssl utility is on the PATH. If not, you'll need to modify PATH or modify sign.sh; the former is easier.
PATH=$PATH:/usr/local/ssl/bin
First, create a keypair file to use with the new certificate. Call this file ca.key. As part of the process you will be prompted to enter a passphrase for the key file. This can be anything you like, but remember it for the next step.
% openssl genrsa -des3 -out ca.key 1024 
Now generate a self-signed certificate, signed by the key you generated in the previous step. Call this certificate ca.crt. As part of the process you will be prompted for the passphrase for the key file ca.key, and for the details of the new certificate. These are arbitrary; they will be presented to web browser users if they ask to see who signed a particular server certificate.
% openssl req -new -x509 -days 365 -key ca.key -out ca.crt  
You can use the file ca.crt to sign any number of server certificates hereafter. Note that ca.crt is not an arbitrary name: the script sign.sh looks for a file with this name.

Step 2 - create the keystore database

This step only has to be done once in the life of an application server instance. Note that once you have done it, you will need to enter the keystore password every time you start the server instance. In the application server administration console, select the `Security' node for the instance to be configured, then the `Manage Database' tab. Enter the password for the keystore an hit `OK'. You will need to restart the server after this step.

Step 3 - generate the CSR

In the application server administration console, select the `Security' node then the `Certificate Management' tab. For `CA E-mail Address' enter anything (you aren't really going to send the e-mail). For `Key Pair File Password' enter the keystore password that you assigned in the previous step. Fill in the information that will go on the new certificate (from `Requestor Name' downwards). This can be anything you like, except that `State or Province' must be at least five letters long, and `Country' must be a valid two-letter country code (e.g., `UK').
      The console generates the CSR, and display the details on the screen. Capture the last part of the display, from `--- BEGIN...' to `---END...' into a file (e.g., cut-and-paste into a text editor). Include the BEGIN and END lines in the file. Save the text file as, for example, bogus.csr.

Sign the CSR with your CA certificate

Use sign.sh as follows:
% sh sign.sh bogus.csr
You may need to replace sign.sh and bogus.csr with their full paths. Note that sign.sh writes its temporary files to the current directory, so if you're not logged in as root you'll need to be in a directory you have write access to. The signed certificate will be called bogus.crt, and located in the same directory as the CSR file. Note that sign.sh isn't doing any magic; if you look in this script you'll see that all it does is generate the rather ugly configuration files that the command openssl ca requires.

Install the signed certificate

In the administration console, select the `Security' node then the `Certificate Management' tab. Select the link `Install' under this tab. Enter the keystore password in the `Key Pair File Password' box. Set the `Certificate Name' field to any name you like -- this is the name that is assigned to the certificate in the server's database, not the name of the certificate. Paste the signed certificate data from the file `bogus.cert' into the `message text' box, and check the button that enables this method of entry. Paste everything between the ---BEGIN and ---END lines, including those lines themselves. Click OK. When the certificate details appear for review, click `Add certificate'. You will need to restart the instances (again) after this step.

Assign the certificate to the listener

Find the name of the HTTP listener that is assigned to the server for which you want to enable SSL. Select the configuration page for that listener in the administration console. Check the box `Enable SSL/TLS' then select the name of the certificate as you assigned it in the last step. Click OK. That's it -- test by pointing a browser at https://server:port and see what happens.

Can I enable both SSL and non-SSL communication for the same (virtual) server?

Yes, but you'll need to create two HTTP listeners, and plumb them into the same virtual server. When you enable SSL for a listener, this has the effect of disabling non-SSL communication.

Can I use SSL to get access to the administration console securely?

Yes. Enabling SSL for the administration server is essentially the same as for individual HTTP listeners. The difference is that the administration server only has one listener, so SSL is either enabled, or not. You can't have both SSL and non-SSL connections to the administration server. The administration server has its own certificate database, and can't share certificates with the server instances. So you'll have to go through the CSR/signing process specifically for the administration server.

Can different virtual servers have different server certificates?

With IP-based virtual hosting, there is usually no problem with assigned different certificates to different virtual servers. All that is necessary is to create an HTTP listener for each virtual server, and install the appropriate certificate in each listener.
      Things are less straightforward with host-based virtual servers. The problems are not specific to the SunONE product, but are consequences of the way that HTTPS works. Like all other HTTP server, S1AS implements host-based virtual servers by looking at the Host: header sent by the browser in each HTTP request. Although all virtual hosts may have the same IP number, the Host: header disambiguates them. The problem is that this header is an ordinary part of the HTTP request, and will not be sent until the SSL handshake is complete. The certificate exchange occurs during the SSL handshake. In short, the server certificate is sent to the browser before the browser will send the information the server requires to select the correct virtual host. In general, therefore, host-based virtual servers cannot have their own server certifcates. The browser will receive the certificate dispatched by the listener, and all virtual servers on that listener have the same certificate.
      In fact, the problem is worse than it first appears. During the SSL handshake, the browser will verify that the hostname assigned to the certificate is the same as the hostname to which it has just issued the request. In general, their must be an exact match. So if two virtual servers, www.acme.com and www.fred.com issue the same certificate, at least one of them is going to be queried by the browser as having an incorrect hostname. If the virtual servers have hostnames that share a domain, then this problem can be overcome using wildcard certificates. A wildcard certificate is one that has a wildcard in the hostname, e.g., *.acme.com. Such a certificate should be accepted by a browser if the certificate is received from any server with a name of the form something.acme.com.
      Because wildcard certificates are a relatively recent innovation, not all browsers support them, although most popular ones do. You can generally expect to pay a bit more for a wildcard certificate than a single-host one.

Can a J2EE application use the Java logging API?

Yes, but bear in mind that not all application servers support this API (they are not obliged to), so your applications may not be portable.

Where do standard error and standard output go?

If your Java components do a System.out.println or a System.err.println, then the output is only captured if the server instance is configured to capture it. This configuration is done through the `Logging' tab of the instance in the administration console. If enabled, standard output and standard error go to server.log in the per-instance logs directory.

What is the class search path within an EJB/Web component?

This question is commonly asked by developers who want to deploy shared class libraries that will be accessible to all EJBs or all Web components in other applications. Consider, for example, a library for doing financial operations, which is used by a number of financial applications. The J2EE specification is quite clear about this: the only way to make the shared library available to all applications is to include it with all applications. The developer cannot rely on anything else being portable. The problem with this strict approach is that many developers don't like it. If the library is large, then it slows deployment and redeployment considerably. If the library is deployed in many different applications, the fact that each application gets its own classloader means that many different copies of the library's bytecode will be resident in memory at the same time. So, many developers prefer to put shared code into a directory where multiple applications can find it.
      Whatever the merits of this approach, you should be aware that it is outside the scope of the J2EE specification, and may not be portable.
      Within an EJB component that is part of an application or stand-alone module, the runtime environment is configured to look for classes in the following places (in the order shown).
  • The JVM bootstrap classes (such as java.lang.String)
  • The JVM's system classpath. This is defined in server.xml for each instance, and can thus be set differently for different instances. Note that the CLASSPATH environment variable is ignored by default, but this can changed in server.xml.
  • JAR files in the directory [instance_dir]/lib within a specific instance, and separate classes in [instance_dir]/lib/classes (in the application server documentation, these locations are called the common classpath).
  • Classes in resource adapters that have been deployed independently of applications
  • Classes in the EJB JAR file itself.
  • JAR files listed in the Class-Path: attribute of the file META-INF/MANIFEST.MF within the EJB JAR file.
For a Web module, the same locations are search, except that rather than looking for referenced JARs in MANIFEST.MF, the web module classloader looks in the directory WEB-INF/lib withing the Web module. If the Web module is part of an application that contains EJBs, then the Web module classloader will look for classes in the EJB modules as well.

What is notably absent in the list of class search locations given above is any mechanism by which the classes in one application or module can locate classes in another. This is intentional; applications and modules are independent, and expected to be isolated. See the next question for ways to get around this isolation.

How can EJBs in one application/module call EJBs in another?

Before answering this question, it's worth pointing out that the J2EE specification provides no mechanism for components to be shared between applications. This is for security purposes: if you are hosting multiple applications, you need to be sure that they cannot interfere with one another, at least not unless you allow it. The isolation between applications and modules is controlled by the classloader scope. For a given EJB module, the classloader will load at all the locations listed in the example above (previous question), but nowhere else.

There are various ways around this `problem' (it isn't really a problem, it's a feature), with varying degrees of elegance. The simplest is to put all the classes that the calling component needs to load onto the system classpath. Don't forget that this includes the stubs of the EJB components. When you deploy the target application (that is, the application whose components will be the targets of other applications' calls), the server generates a `client JAR' containing classes that calling components will need. If the application EAR file is called `X', then this file will be called XApplicationClient.jar, and will be found below the applications directory for a particular instance. This JAR is really intended to support the use of stand-alone clients, but one EJB application can be seen as a stand-alone client of another.
      So copying XApplicationClient.jar to [instance_dir]/lib makes the classes the EJBs in application X available to all other applications. These other applications will look up EJBs in the target application using their JNDI names; they can't use java:comp/env names, because the java:comp/env namespace has application scope, not instance scope.

Using the lib directory makes the target application accessible to all other applications in that server instance, which may be too wide a scope. If you just want to make EJBs in application X available to application Y, then a better approach is to package XApplicationClient.jar inside one of the EJB modules in application Y. Then, in the MANIFEST.MF file for that EJB module, reference the included XApplicationClient.jar using a Class-Path: statement.

   
Search

WebThis site

Shameless plug

By the author of this site. Buy on-line from Amazon USA | UK

Editorial
So you want to be a university lecturer? Read this first!

Speak like your boss: new developments in managerese

Computing features
File handling in the Linux kernel: an in-depth look at how Linux handles files, filesystems, and file I/O

All sorts of Linux stuff

Confused about CLASSPATH? answers are here

First steps in EJB using jBoss (recently revised for jBoss 3.2)