BEA Home | Events | Solutions | Partners | Products | Services | Download | Developer Center | WebSUPPORT
| WebLogic Server Doc Home | Developing Applications | Previous Topic | Next Topic | Contents | Index | View as PDF

Programming Topics

The following sections contain information about programming in the WebLogic Server environment, including descriptions of useful WebLogic Server facilities and advice about using various programming techniques:

- Logging Messages

- Using Threads in WebLogic Server

- Using JavaMail with WebLogic Server Applications

- Programming Applications for WebLogic Server Clusters

Logging Messages

Each WebLogic Server instance has a log file that contains messages generated from that server. Your applications can write messages to the log file using internationalization services that access localized message catalogs. If localization is not required, you can use the weblogic.logging.NonCatalogLogger class to write messages to the log. This class can also be use in client applications to write messages in a client-side log file.

This section describes how to use the NonCatalogLogger class. See the BEA WebLogic Server Internationalization Guide for details on using the internationalization interface.

The log file name, location, and other properties can be administered in the Administration Console. Log messages written via the NonCatalogLogger class contain the following information.

Table 4-1 Log Message Format

Property | Description
--- | ---
Localized Timestamp | Date and time when message originated, including the year, month, day of month, hours, minutes and seconds.
millisecondsFromEpoch | The origination time of the message, in milliseconds since the epoch.
ServerName, MachineName, ThreadId, TransactionId | The origin of the message. TransactionId is present only for messages logged within the context of a transaction.
User Id | User on behalf of whom the system was executing when the error was reported.
Subsystem | Source of the message, for example EJB, JMS, or RMI. A user application supplies a Subsystem String in the NonCatalogLogger constructor.
Message Id | A unique six-digit identifier for the message. All message IDs through 499000 are reserved for WebLogic Server.
Severity | One of the following severity values:
Debug | Should be output only when the server/application is configured in a debug mode. May contain detailed information about operations or the state of the server/application.
Informational | Used to log normal operations for later examination.
Warning | A suspicious operation, event, or configuration that does not affect the normal operation of the server/application.
Error | A user level error. The system/application can handle the error with no interruption and with limited degradation in service.
In addition to the above, some severity levels are reserved for WebLogic Server messages:
Notice | A warning message. A suspicious operation or configuration that does not affect the normal operation of the server.
Critical | A system/service level error. The system is able to recover, perhaps with a momentary loss or permanent degradation of service.
Alert | A particular service is in an unusable state. Other parts of the system continue to function. Automatic recovery is not possible and the immediate attention of the administrator is required to resolve the problem.
Emergency | The server is in an unusable state. This is used to designate severe system failures or panics.
ExceptionName | If the message is logging an Exception, this field contains the name of the Exception.
Message text | For WebLogic Server messages, this field contains the "short description" of the message defined in the system message catalog.

To use NonCatalogLogger, import the weblogic.logging.NonCatalogLogger class and call the constructor with a subsystem String. Here is an example using the subsystem name "MyApp":

>     import weblogic.logging.NonCatalogLogger;
>     ...
>     NonCatalogLogger mylogger = new NonCatalogLogger("MyApp");

NonCatalogLogger provides the methods debug(), info(), warn(), and error(), which write messages with Debug, Informational, Warning, and Error severities, respectively. Each method has two signatures, one that takes a String message argument, and another that takes a String message and a java.lang.Throwable argument. If you use the latter form, the log message includes a stack trace.

Here is an example of writing an informational message, without stack trace, to the log:

>     mylogger.info("MyApp initialized.");

If you are using NonCatalogLogger in a Java client, you specify the name of the log file on the java command line, using the weblogic.log.FileName Java system property. For example:

>     java -Dweblogic.log.FileName=myapp.log myapp

If you have special processing requirements for some log messages, you can add your own message handlers.Your message handler provides a filter to select the messages it is interested in processing. For each log message, the WebLogic Server logging infrastructure raises a JMX notification, which is delivered to the registered message handlers with filters that match the message.

See weblogic.management.logging.WebLogicLogNotification information about using this JMX feature.

Using Threads in WebLogic Server

WebLogic Server is a sophisticated, multi-threaded application server and it carefully manages resource allocation, concurrency, and thread synchronization for the components it hosts. To obtain the greatest advantage from WebLogic Server's architecture you should construct your applications from components created using the standard J2EE APIs.

It is advisable to avoid application designs that require creating new threads in server-side components for several reasons:

- Applications that create their own threads do not scale well. Threads in the JVM are a limited resource that must be allocated thoughtfully. Your applications may break or cause WebLogic Server to thrash when the server load increases. Problems such as deadlocks and thread starvation may not appear until the application is under a heavy load.

- Multithreaded components are complex and difficult to debug. Interactions between application-generated threads and WebLogic Server threads are especially difficult to anticipate and analyze.

There are some situations where creating threads may be appropriate, in spite of these warnings. For example, an application that searches several repositories and returns a combined result set can return results sooner if the searches are done asynchronously using a new thread for each repository instead of synchronously using the main client thread.

If you decide you must use threads in your application code, your should create a pool of threads so that you can control the number of threads your application creates. Like a JDBC connection pool, you allocate a given number of threads to a pool, and then obtain an available thread from the pool for your runnable class. If all threads in the pool are in use, wait until one is returned. A thread pool can help avoid performance issues and will also allow you to optimize the allocation of threads between WebLogic Server execution threads and your application.

Be sure you understand where your threads can deadlock and handle the deadlocks when they occur. Review your design carefully to ensure that your threads do not compromise the security system.

To avoid undesirable interactions with WebLogic Server threads, do not let your threads call into WebLogic Server components. For example, do not use enterprise beans or servlets from threads that you create. Application threads are best used for independent, isolated tasks, such as conversing with an external service with a TCP/IP connection or, with proper locking, reading or writing to files. A short-lived thread that accomplishes a single purpose and ends (or returns to the thread pool) is less likely to interfere with other threads.

Be sure to test multithreaded code under increasingly heavy loads, adding clients even to the point of failure. Observe the application performance and WebLogic Server behavior and then add checks to prevent failures from occurring in production.

Using JavaMail with WebLogic Server Applications

WebLogic Server includes the JavaMail API version 1.1.3 reference implementation from Sun Microsystems. Using the JavaMail API, you can add email capabilities to your WebLogic Server applications. JavaMail provides access from Java applications to IMAP- and SMTP-capable mail servers on your network or the Internet. It does not provide mail server functionality; so you must have access to a mail server to use JavaMail.

Complete documentation for using the JavaMail API is available on the JavaMail page on the Sun Web site. This section describes how you can use JavaMail in the WebLogic Server environment.

The weblogic.jar file contains the javax.mail and javax.mail.internet packages from Sun. weblogic.jar also contains the Java Activation Framework (JAF) package, which JavaMail requires.

The javax.mail package includes providers for Internet Message Access protocol (IMAP) and Simple Mail Transfer Protocol (SMTP) mail servers. Sun has a separate POP3 provider for JavaMail, which is not included in weblogic.jar. You can download the POP3 provider from Sun and add it to the WebLogic Server classpath if you want to use it.

About JavaMail Configuration Files

JavaMail depends on configuration files that define the mail transport capabilities of the system. The weblogic.jar file contains the standard configuration files from Sun, which enable IMAP and SMTP mail servers for JavaMail and define the default message types JavaMail can process.

Unless you want to extend JavaMail to support additional transports, protocols, and message types, you do not have to modify any JavaMail configuration files. If you do want to extend JavaMail, you should download JavaMail from Sun and follow Sun's instructions for adding your extensions. Then add your extended JavaMail package in the WebLogic Server classpath in front of weblogic.jar.

Configuring JavaMail for WebLogic Server

To configure JavaMail for use in WebLogic Server, you create a Mail Session in the WebLogic Server Administration Console. This allows server-side components and applications to access JavaMail services with JNDI, using Session properties you preconfigure for them. For example, by creating a Mail Session, you can designate the mail hosts, transport and store protocols, and the default mail user in the Administration Console so that components that use JavaMail do not have to set these properties. Applications that are heavy email users benefit because WebLogic Server creates a single Session object and makes it available via JNDI to any component that needs it.

1. In the Administration Console, click on the Mail node in the left pane of the Administration Console.

2. Click Create a New Mail Session.

3. Complete the form in the right pane, as follows:

   - In the Name field, enter a name for the new session.

   - In the JNDIName field, enter a JNDI lookup name. Your code uses this string to look up the javax.mail.Session object.

   - In the Properties field, enter properties to configure the Session. The property names are specified in the JavaMail API Design Specification. JavaMail provides default values for each property, and you can override the values in the application code. The following table lists the properties you can set in this field.

Table 4-2 Mail Session Properties Field

Property | Description | Default
--- | --- | ---
mail.store.protocol | The protocol to use to retrieve email. Example: mail.store.protocol=imap | The bundled JavaMail library has support for IMAP.
> mail.transport.protocol | The protocol to use to send email. Example:
>     mail.transport.protocol=smtp
| The bundled JavaMail library has support for SMTP.
> mail.host | The name of the mail host machine. Example:
>     mail.host=mailserver
| The default is the local machine.
> mail.user | The name of the default user for retrieving email. Example:
>     mail.user=postmaster
| The default is the value of the user.name Java system property.
> mail.protocol.host | The mail host for a specific protocol. For example, you can set mail.SMTP.host and mail.IMAP.host to different machine names. Examples:
>     mail.smtp.host=mail.mydom.com
>     mail.imap.host=localhost
| The value of the mail.host property.
> mail.protocol.user | The protocol-specific default user name for logging into a mailer server. Examples:
>     mail.smtp.user=weblogic
>     mail.imap.user=appuser
| The value of the mail.user property.
> mail.from | The default return address. Examples:
>     mail.from=master@mydom.com
| username@host
mail.debug | Set to True to enable JavaMail debug output. | False

You can override any properties set in the Mail Session in your code by creating a Properties object containing the properties you want to override. Then, after you lookup the Mail Session object in JNDI, call the Session.getInstance() method with your Properties to get a customized Session.

Sending Messages with JavaMail

Here are the steps to send a message with JavaMail from within a WebLogic Server component:

1. Import the JNDI (naming), JavaBean Activation, and JavaMail packages. You will also need to import java.util.Properties:

   >     import java.util.*;
   >     import javax.activation.*;
   >     import javax.mail.*;
   >     import javax.mail.internet.*;
   >     import javax.naming.*;

2. Look up the Mail Session in JNDI:

   >     InitialContext ic = new InitialContext();
   >     Session session = (Session) ic.lookup("myMailSession");

3. If you need to override the properties you set for the Session in the Administration Console, create a Properties object and add the properties you want to override. Then call getInstance() to get a new Session object with the new properties.

   >     Properties props = new Properties();
   >     props.put("mail.transport.protocol", "smtp");
   >     props.put("mail.smtp.host", "mailhost");
   >     // use mail address from HTML form for from address
   >     props.put("mail.from", emailAddress);
   >     Session session2 = session.getInstance(props);

4. Construct a MimeMessage. In the following example, to, subject, and messageTxt are String variables containing input from the user.

   >     Message msg = new MimeMessage(session2);
   >     msg.setFrom();
   >     msg.setRecipients(Message.RecipientType.TO,
   >                                         InternetAddress.parse(to, false));
   >     msg.setSubject(subject);
   >     msg.setSentDate(new Date());
   >     // Content is stored in a MIME multi-part message
   >     // with one body part
   >     MimeBodyPart mbp = new MimeBodyPart();
   >     mbp.setText(messageTxt);

   >     Multipart mp = new MimeMultipart();
   >     mp.addBodyPart(mbp);
   >     msg.setContent(mp);

5. Send the message.

   >     Transport.send(msg);

The JNDI lookup can throw a NamingException on failure. JavaMail can throw a MessagingException if there are problems locating transport classes or if communications with the mail host fails. Be sure to put your code in a try block and catch these exceptions and handle them.

Reading Messages with JavaMail

The JavaMail API allows you to connect to a message store, which could be an IMAP server or POP3 server. Messages are stored in folders. With IMAP, message folders are stored on the mail server, including folders that contain incoming messages and folders that contain archived messages. With POP3, the server provides a folder that stores messages as they arrive. When a client connects to a POP3 server, it retrieves the messages and transfers them to a message store on the client.

Folders are hierarchical structures, similar to disk directories. A folder can contain messages or other folders. The default folder is at the top of the structure. The special folder name INBOX refers to the primary folder for the user, and is within the default folder. To read incoming mail, you get the default folder from the store, and then get the INBOX folder from the default folder.

The API provides several options for reading messages, such as reading a specified message number or range of message numbers, or pre-fetching specific parts of messages into the folder's cache. See the JavaMail API for more information.

Here are steps to read incoming messages on a POP3 server from within a WebLogic Server component:

1. Import the JNDI (naming), JavaBean Activation, and JavaMail packages. You will also need to import java.util.Properties:

   >     import java.util.*;
   >     import javax.activation.*;
   >     import javax.mail.*;
   >     import javax.mail.internet.*;
   >     import javax.naming.*;

2. Look up the Mail Session in JNDI:

   >     InitialContext ic = new InitialContext();
   >     Session session = (Session) ic.lookup("myMailSession");

3. If you need to override the properties you set for the Session in the Administration Console, create a Properties object and add the properties you want to override. Then call getInstance() to get a new Session object with the new properties:

   >     Properties props = new Properties();
   >     props.put("mail.store.protocol", "pop3");
   >     props.put("mail.pop3.host", "mailhost");
   >     Session session2 = session.getInstance(props);

4. Get a Store object from the Session and call its connect() method to connect to the mail server. To authenticate the connection, you need to supply the mailhost, username, and password in the connect method:

   >     Store store = session.getStore();
   >     store.connect(mailhost, username, password);

5. Get the default folder, then use it to get the INBOX folder:

   >     Folder folder = store.getDefaultFolder();
   >     folder = folder.getFolder("INBOX");

6. Read the messages in the folder into an array of Messages:

   >     Message[] messages = folder.getMessages();

7. Operate on messages in the Message array. The Message class has methods that allow you to access the different parts of a message, including headers, flags, and message contents.

Reading messages from an IMAP server is similar to reading messages from a POP3 server. With IMAP, however, the JavaMail API provides methods to create and manipulate folders and transfer messages between them. If you use an IMAP server, you can implement a full-featured, Web-based mail client with much less code than if you use a POP3 server. With POP3, you must provide code to manage a message store via WebLogic Server, possibly using a database or file system to represent folders.

Programming Applications for WebLogic Server Clusters

JSPs and Servlets that will be deployed to a WebLogic Server cluster must observe certain requirements for preserving session data. See Session Programming Requirements in Using WebLogic Server Clusters for more information.

EJBs deployed in a WebLogic Server cluster have certain restrictions based on EJB type. See The WebLogic Server EJB Container for information about the capabilities of different EJB types in a cluster. EJBs can be deployed to a cluster by setting clustering properties in the EJB deployment descriptor. weblogic-ejb-jar.xml Deployment Descriptors describes the XML deployment elements relevant for clustering.

If you are developing either EJBs or custom RMI objects for deployment in a cluster, also refer to Using WebLogic JNDI in a Clustered Enviroment to understand the implications of binding clustered objects in the JNDI tree.

Copyright © 2001 BEA Systems, Inc. All rights reserved. Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.