WorkManager

Free WebLogic Server Course

We are bringing you a free course on WebLogic Server. In the course you will learn the following:

  • Introduction
    • WebLogic Server architecture (domain, admin server, managed server, node manager, cluster, machine)
    • WebLogic Server internal architecture (listen threads, socket muxer, execute queue, execute threads)
  • JVM Tuning
    • Code generation
    • Memory management
    • Garbage collection performance
    • JRockit Mission Control
  • Deployment
    • Packaging applications recommendations
    • Deployment descriptors
    • Deployment plans
    • Work Manager configuration
  • Diagnostic Framework (logging, instrumentation, harvesting, watching and notifying)
  • Class Loading
    • Bundled libraries
    • Shared libraries
    • Filtering class loader
  • Security
    • JAAS introduction
    • Embedded LDAP
    • WebLogic Server security providers
    • Secure communications (SSL and TLS)
  • Configure Resources
    • Configure data sources
    • Monitoring resources
    • Configure JMS environment
    • Migrating singleton services (leasing, migratable targets, service migration policy)
  • Clustering
    • Unicast or multicast?
    • Node manager and machine set-up
    • Denial of service configuration
    • Network channels
    • Vertical and horizontal scaling
    • Caching by using Coherence
    • Apache HTTP Server and WebLogic plug-in set-up
  • Scripting (WLST)

Note that this is a course you can do at your own pace. The exercises lead you step-by-step through the process of installing, configuring, deploying etcetera. The material consists of the following:

Have fun!


Configuring Enterprise Beans in WebLogic

This discussion of WebLogic EJB features concentrates on features useful in the creation of classic Java EE applications using EJB components for the business layer of the application. One very important feature is the EJB container. WebLogic’s EJB container is implemented using Spring, based on the Pitchfork project, which was co-developed by SpringSource and WebLogic engineers.

EJB Container

The EJB container is a fundamental part of the EJB architecture. In a nutshell, the EJB container provides the environment used to host and manage the EJB components deployed in the container. The container is responsible for providing a standard set of services, including caching, concurrency, persistence, security, transaction management, and locking services. The container also provides distributed access and lookup functions for hosted components, and it intercepts all method invocations on hosted components to enforce declarative security and transaction contexts. The EJB container is not a single Java class, nor is it a single API or service accessible to the contained components or external client code. It is more of an abstract concept implemented by each server vendor in a unique fashion.

EJB Lifecycle

One of the key responsibilities of the EJB container is the management of EJB component lifecycles. Bean instances are pooled and reused by the container to reduce the number of object instantiations. For example the lifecycle of a stateless session bean is as follows:

  1. The client obtains a reference to the stateless sesson bean. There are three options here. First, the reference can be injected into the client via an @EJB annotation. Second, the reference can be bound into the client’s local java:comp/env environment, using the @EJB annotation at class-level or a deployment descriptor entry, and the client can retrieve the reference with a JNDI lookup. Third, the client can look up the stateless session bean in the server’s global JNDI tree.
  2. The client invokes a business method on the bean reference.
  3. The container can reuse an existing instance of the stateless session bean from a pool, if available, or can instantiate a new bean instance. If a bean instance is newly created, the container will first perform dependency injection. If the stateless session bean implements the optional javax.ejb.SessionBean interface, the container will call setSessionContext. The session context will also be injected to any SessionContext field marked with the @Resource annotation. After completing injection of the session context and other dependencies, the container will call any methods marked with the @PostConstruct annotation.
  4. The container starts a transaction, if appropriate. This is controlled by the @javax.ejb.TransactionManagement and @javax.ejb.TransactionAttribute annotations.
  5. The container invokes the called business method on the bean instance, and the bean performs the desired operation.
  6. The container commits the transaction, if appropriate.
  7. The results of the business method call are returned to the client.
  8. The client may invoke additional business methods on the bean reference, each of which may end up invoking methods on a different bean instance.
  9. At some point, if the container decides to reduce the size of the bean instance pool, the container invokes any @PreDestroy methods on the bean instance, or ejbRemove if the bean implements the SessionBean interface. It is important to understand that this decision is not related to any client action.

There is a stronger link between the lifecycle of a stateful session bean and the client’s use of its reference:

  1. The client obtains a reference to the stateful session bean.
  2. The container instantiates a new bean instance. The container will perform dependency injection. If the stateful session bean implements the optional javax.ejb.SessionBean interface, the container will call setSessionContext. The session context will also be injected to any SessionContext field marked with the @Resource annotation. Any methods marked with the @PostConstruct will then be called.
  3. The client invokes a business method on the bean reference.
  4. The container starts a transaction, if appropriate.
  5. The container invokes a business method on the bean instance, and the bean performs the desired operation.
  6. The container commits the transaction, if appropriate.
  7. The results of the business method call are returned to the client.
  8. The client may invoke additional business methods on the bean reference and is assured that these additional calls will go to the same instance of the bean.
  9. The client calls a method annotated with @javax.ejb.Remove when it is done with the stateful session bean.
  10. The container invokes any @PreDestroy methods on the bean instance, or ejbRemove if the bean implements the SessionBean interface.

This introduction to the lifecycle of session EJB components represents a simplified view of the process. Additional complexities are introduced by limitations in the pool and cache sizes that you need to understand to configure your application properly. We cover some of these complexities later.

EJB Compilation

The normal packaging and deployment technique for EJB components involves the execution of the WebLogic application compiler weblogic.appc to create a complete EJB archive file containing all of the runtime container classes required for the EJB components. Here is a terminal session showing the effect of compiling an EJB jar with weblogic.appc. Initially, the EJB jar just contains the classes shown after the first jar command. After weblogic.appc has been run on the jar file, it contains several other generated classes.

jar tf model.jar

META-INF/MANIFEST.MF
META-INF/persistence.xml
model/client/Client.class
model/entities/Film.class
model/entities/FilmId.class
model/entities/Persoon.class
model/interceptors/VideotheekLogger.class
model/interceptors/VideotheekPersoonInterceptor.class
model/logic/Videotheek.class
model/logic/VideotheekBean.class
model/logic/VideotheekException.class
model/logic/Videotheekmessage-driven bean.class
model/logic/VideotheekWizard.class
model/logic/VideotheekWizardBean.class
model/utils/WebLogicTransactionController.class
java weblogic.appc model.jar
jar tf model.jar

META-INF/MANIFEST.MF
META-INF/
META-INF/persistence.xml
model/
model/client/
model/client/Client.class
model/entities/
model/entities/Film.class
model/entities/FilmId.class
model/entities/Persoon.class
model/interceptors/
model/interceptors/VideotheekLogger.class
model/interceptors/VideotheekLogger_94cl58_Impl$1.class
model/interceptors/VideotheekLogger_94cl58_Impl$2.class
model/interceptors/VideotheekLogger_94cl58_Impl.class
model/interceptors/VideotheekPersoonInterceptor.class
model/interceptors/VideotheekPersoonInterceptor_lr768n_Impl$1.class
model/interceptors/VideotheekPersoonInterceptor_lr768n_Impl$2.class
model/interceptors/VideotheekPersoonInterceptor_lr768n_Impl.class
model/logic/
model/logic/ejb_VideotheekWizard_vl07y8_Impl$1.class
model/logic/ejb_VideotheekWizard_vl07y8_Impl$2.class
model/logic/ejb_VideotheekWizard_vl07y8_Impl.class
model/logic/ejb_VideotheekWizard_vl07y8_Intf.class
model/logic/ejb_VideotheekWizard_vl07y8_VideotheekWizardImpl.class
model/logic/ejb_VideotheekWizard_vl07y8_VideotheekWizardImplRTD.xml
model/logic/ejb_VideotheekWizard_vl07y8_VideotheekWizardImpl_1031_WLStub.class
model/logic/ejb_VideotheekWizard_vl07y8_VideotheekWizardImpl_WLSkel.class
model/logic/ejb_VideotheekWizard_vl07y8_VideotheekWizardIntf.class
model/logic/ejb_Videotheek_l2bcbu_Impl.class
model/logic/ejb_Videotheek_l2bcbu_Intf.class
model/logic/ejb_Videotheek_l2bcbu_VideotheekImpl.class
model/logic/ejb_Videotheek_l2bcbu_VideotheekImplRTD.xml
model/logic/ejb_Videotheek_l2bcbu_VideotheekImpl_1031_WLStub.class
model/logic/ejb_Videotheek_l2bcbu_VideotheekImpl_WLSkel.class
model/logic/ejb_Videotheek_l2bcbu_VideotheekIntf.class
model/logic/Videotheek.class
model/logic/VideotheekBean.class
model/logic/VideotheekException.class
model/logic/Videotheekmessage-driven bean.class
model/logic/VideotheekWizard.class
model/logic/VideotheekWizardBean.class
model/utils/
model/utils/WebLogicTransactionController.class
_WL_GENERATED

It is possible to deploy the raw EJB archive file to WebLogic, without first running it through weblogic.appc. When this is done, the actual compilation step is deferred until the EJB container processes the archive file during the deployment of the application. WebLogic will also recompile on deployment if it detects that any of the files in the jar archive have changed or if the jar was created using a different version of the compiler, even if the difference is only a service pack. This information is stored in the _WL_GENERATED file. Automatic compilation on deployment is a good development time convenience, but will increase the length of time it takes your EJB to deploy. A further advantage of running weblogic.appc is that it will enhance persistent classes.

EJB References

Session beans can define remote business interfaces by annotating them with javax.ejb.Remote.

package model.logic;
@Remote
public interface Videotheek {...}

@Stateless(name="Videotheek", mappedName = "ejb/Videotheek")
public class VideotheekBean implements Videotheek {...}

Remote clients can look up the session bean in JNDI and invoke it over RMI. The Java EE 5 specification does not define a portable way to map the EJB to a well-known name in JNDI. Standardized mappings will be included in Java EE 6. In the meantime, the mapping to JNDI is vendor-specific behavior. WebLogic provides two options for mapping a session bean’s remote business interface into the global JNDI tree. The mapping can be specified in the weblogic-ejb-jar.xml deployment descriptor, or the mappedName attribute of the @Stateless or @Stateful annotations can be used. Here is an example weblogic-ejb-jar.xml descriptor that maps the Videotheek remote business interface to the global JNDI name ejb/Videotheek.

<weblogic-ejb-jar ...>
	<weblogic-enterprise-bean>
		<ejb-name>Videotheek</ejb-name>
		<stateless-session-descriptor>
			<business-interface-jndi-name-map>
				<business-remote>model.logic.Videotheek</business-remote>
				<jndi-name>ejb/Videotheek</jndi-name>
			</business-interface-jndi-name-map>
		</stateless-session-descriptor>
	</weblogic-enterprise-bean>
</weblogic-ejb-jar>

The value set in the ejb-name element must match the name of the EJB. There is no direct relation between the name of the EJB and its JNDI names. The name can be set using the name attribute of the @Stateless or @Stateful annotations, and defaults to the unqualified name of the bean class. The business-interface-jndi-name-map element has at most one mapping for each remote business interface of the EJB. Take care when specifying the ejb-name and business-remote values. If you misspell these, WebLogic will not complain when the EJB is deployed; the EJB will simply not be bound to the JNDI name.

The other way to bind a session bean into the global JNDI tree is to use the mappedName element of the @Stateless or @Stateful annotations. A bean can have multiple remote interfaces. The JNDI name used by WebLogic is the supplied mappedName further qualified with the remote interface class name. In our example, the global JNDI name will be ejb/Videotheek#model.logic.Videotheek. The way the JNDI name is constructed is specific to WebLogic. The EJB specification explicitly warns that using mappedName is non-portable. There are two minor disadvantages to using mappedName to bind an EJB into the global JNDI tree. First, it does not allow an arbitrary JNDI name to be specified – the interface name will always be appended. Second, it is specified within the source code, but is non-portable. It is prefered to keep vendor-specific behavior in deployment descriptors, but the simplicity of placing all the binding information in a single annotation is a compelling counter-argument.

EJBs rarely exist in isolation. Their implementations often need to call other EJBs, and require a way to look up these EJBs. The EJB specification allows an EJB to declare references to other EJBs, either in its deployment descriptor, or by using the @EJB annotation. This avoids the need to hard code the global JNDI names or locations of the referenced beans in the EJB implementation code. The references can be customized by modifying the deployment descriptor or using a deployment plan. This makes the EJB a more reusable component. The ejb-ref and ejb-local-ref elements in the ejb-jar.xml descriptor are used to map references to other EJBs into the local java:comp/env environment. The application code then uses logical JNDI names in the java:comp/env namespace, and the deployment descriptor specifies how the container should resolve these names. Setting up an EJB reference in deployment descriptors requires coordinated changes to the code, the ejb-jar.xml descriptor, and sometimes the weblogic-ejb-jar.xml descriptor as well. The annotation and dependency injection features introduced in EJB 3.0 are much more convenient. The @EJB annotation keeps the declaration of an EJB reference within the code, but the mapping can still be overridden if necessary in a deployment descriptor.

It is very common for EJB components to refer to other EJB components contained in the same Java EE application. All EJB components in the same EJB archive file are in the same application, as are all EJB components in different archive files packaged in a single enterprise application (.ear). EJBs can, of course, look up each other directly using known global JNDI names.

public class LookUp {

    public static Context context = null;

    private LookUp() {
    }

    static {
        try {
            context = new InitialContext();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public static Videotheek getVideotheek() {
        Videotheek videotheek = null;
        try {
            videotheek = (Videotheek)context.lookup("ejb/Videotheek#model.logic.Videotheek");
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return videotheek;
    }
}

This technique increases the coupling between EJB components because the global JNDI name of the referenced EJB is hard coded. When a global JNDI lookup is used directly, the container knows nothing of the reference. Alternatively, an EJB reference can be declared to the container. The container resolves the target EJB during deployment, and makes it available in the local java:comp/env environment.

videotheek = (Videotheek)context.lookup("java:comp/env/ejb/Videotheek");

EJB 3.0 has added a lookup convenience method to EJBContext that provides direct access to an EJB’s environment without the need to use JNDI APIs, so the following will also work.

@Stateless(name = "ejb/Videotheek", mappedName = "ejb/Videotheek")
public class VideotheekBean implements Videotheek {

    VideotheekWizard wizard;

    @Resource
    EJBContext ejbContext;

    @PostConstruct
    public void init() {
        wizard = (VideotheekWizard)ejbContext.lookup("ejb/VideotheekWizard");
    }
}

There are three ways to map an environment entry to the target EJB. In the first approach, the referring component declares the reference by including an ejb-ref element (for remote business interfaces) or an ejb-local-ref element (for local business interfaces) in the ejb-jar.xml descriptor.

<session>
	<ejb-name>VideotheekBean</ejb-name>
	<ejb-local-ref>
		<ejb-ref-name>ejb/Wizard</ejb-ref-name>
		<local>model.logic.VideotheekWizard</local>
	</ejb-local-ref>
</session>

The ejb-local-reference-description element in the weblogic-ejb-jar.xml descriptor is then used to map this reference to a particular global JNDI name.

<ejb-local-reference-description>
	<ejb-ref-name>ejb/Wizard</ejb-ref-name> <!-- Matches name in ejb-jar.xml -->
	<jndi-name>ejb/VideotheekWizard</jndi-name>
</ejb-local-reference-description>

In the second approach, the referring component includes an ejb-link element in the ejb-local-ref element in ejb-jar.xml, specifying the name of the other EJB component.

<ejb-local-ref>
	<ejb-ref-name>ejb/VideotheekWizard</ejb-ref-name>
	<local>model.logic.VideotheekWizard</local>
	<ejb-link>VideotheekWizardBean</ejb-link>
</ejb-local-ref>

With this approach there is no need to bind the referenced EJB into the global JNDI tree. No elements are required in the weblogic-ejb-jar.xml descriptor, which means the code is portable between containers. The container automatically maps the ejb/VideotheekWizard reference to the model.logic.VideotheekWizard business interface and binds it to the referring EJB’s environment at java:comp/env/ejb/VideotheekWizard. The name VideotheekWizardBean is the logical name of the EJB set using the name element of the @Stateless or @Stateful annotations or, by default, the unqualified name of the bean class. The ejb-link element may also provide the name of the EJB archive file hosting the desired component.

<ejb-link>some.jar#VideotheekWizard</ejb-link>

This is necessary only if two EJBs are in two different archive files and use the same logical name. The third approach uses the @EJB annotation on the referring EJB class.

@EJB(name="ejb/VideotheekWizard", beanInterface=model.logic.VideotheekWizard.class)
@Stateless
public class VideotheekWizardBean implements VideotheekWizard {...}

This approach is similar to using an ejb-local-ref, but has the benefit of requiring no deployment descriptor entries. A JNDI lookup of java:comp/env/ejb/VideotheekWizard is still required. The @EJB annotation also supports a beanName attribute, which is interpreted in the same way as the value of an ejb-link element. In this case we have left it out, so the container will attempt to resolve the reference based on the type of the business interface. This will work, so long as a single EJB implements that business interface. The container will perform similar auto-wiring if we declare an ejb-ref or an ejb-local-ref without an ejb-link or a binding in weblogic-ejb-jar.xml. Finally, EJB 3.0 dependency injection can be used to remove the need for an explicit lookup. The @EJB annotation is used again, but applied to a field of the referring EJB, rather than at class level.

@Stateless
public class VideotheekBean implements Videotheek {
    @EJB
    private VideotheekWizard videotheekWizard;
}

It does not get much simpler than this. When VideotheekBean is deployed, the container will inject a reference to an EJB with the appropriate business interface. This is portable and requires no deployment descriptor entries. The EJB will be bound to java:comp/env/model.logic.Videotheek/VideotheekWizard, but because the container has set the reference, there is no need for a JNDI lookup. The beanInterface and beanName attributes can be used for disambiguation if the reference type is a superclass of the business interface, or if it is implemented by multiple EJBs in the application.

EJB components located in different enterprise application archive (.ear) files or other EJB jar files not part of the current application, are considered external components whether or not they run in the same WebLogic instance. These components are not part of the same deployment, so the ejb-link mechanism for referring to other components is not available. Components must use either global JNDI names or include appropriate ejb-ref elements in ejb-jar.xml and ejb-reference-description elements in the weblogic-ejb-jar.xml descriptor to look up external components. Note that local business interfaces can only be used within an application, so external components must be looked up and invoked through their remote business interfaces. Because the components are external to the current application and more likely to change their global JNDI names, it is suggested to use ejb-ref and ejb-reference-description elements instead of directly using global JNDI names. The ejb-reference-description allows lookup of components in the host WebLogic’s global JNDI tree. If the location of the referenced EJB is truly remote, use WebLogic’s Foreign JNDI Provider feature to create a binding in the global JNDI tree, and place the configuration of its physical location under the administrator’s control.

Pass-by value or Pass-by-reference

The Java EE specification requires that EJB components invoked through their remote interfaces must use pass-by-value semantics, meaning that method parameters are copied during the invocation. Changes made to a parameter in the bean method are not reflected in the caller’s version of the object. Copying method parameters is required in the case of a true remote invocation, of course, because the parameters are serialized by the underlying RMI infrastructure before being provided to the bean method. Pass-by-value semantics are also required between components located in different enterprise applications in the same Java virtual machine due to classloader constraints. EJB components located in the same enterprise application archive (.ear) file are loaded by the same classloader and have the option of using pass-by-reference semantics for all invocations, eliminating the unnecessary copying of parameters passed during the invocation and improving performance. Set the enable-call-by-reference parameter to true in the weblogic-ejb-jar.xml descriptor file to enable this feature for each bean in your application. Local references always use pass-by-reference semantics and are unaffected by the enable-call-by-reference setting. When you deploy an EJB with a remote interface and do not enable call by reference, WebLogic will issue a warning of the performance cost.

EJB Pooling

WebLogic maintains a pool of stateless session EJB instances for each stateless session bean deployment. This pool improves performance, because a client request can be handled immediately by any free initialized EJB instance. By default, the pool starts empty, and grows on demand. This can be controlled with the initial-beans-in-free-pool and max-beans-in-free-pool deployment descriptor parameters. The stateless session bean pool can also shrink in size. A bean instance will be removed if it has been idle for more than the value of idle-timeout-seconds (by default, 600 seconds), and there are more than max-beans-in-free-pool beans in the pool. The default value of 0 for initial-beans-in-free-pool is fine for most stateless session bean deployments. You may wish to set initial-beans-in-free-pool if your stateless session bean is particularly expensive to initialize so that you force the initialization of a number of bean instances at deployment time, and you ensure that pool shrinking does not discard these beans. The default value of 1000 for max-beans-in-free-pool is also appropriate for most stateless session bean deployments. Unless an stateless session bean recursively calls itself (the only way that a single execute thread might require more than one active instance of the stateless session bean), this default limit will not practically be reached.

If you set max-beans-in-free-pool, you are choosing deliberately to throttle your application. If there are no idle bean instances, an execute thread making a new request will block until a bean becomes available or the transaction times out. If remote clients call the stateless session bean, it is a good idea to use the dispatch-policy deployment descriptor element to assign the EJB instance to a custom work manager with a max-threads-constraint set to the same value as max-beans-in-free-pool. The max-threads-constraint will mean that surplus requests are left in the self-tuning thread pool’s execute queue, rather than requiring an execute thread. The max-beans-in-free-pool setting is still required to ensure that non-remote calls to the stateless session bean (which will not use the work manager specified by the dispatch-policy) do not cause the pool size to increase beyond the desired limit.

EJB Cache

WebLogic creates stateful session bean instances as they are needed to service client requests. Between requests these instances reside in a bean-specific cache in the active state, ready for the next request. The size of the cache is limited by the max-beans-in-cache element in the weblogic-ejb-jar.xml deployment descriptor file. The default value is 1000. So long as your application never requires more than max-beans-in-cache instances of the stateful session bean at any given time to service all concurrent clients, there is no contention for the cache and performance is optimal. If you limit the number of beans in the cache, WebLogic may be forced to manage the cache in a fairly active manner using the following rules:

  • If the cache is full, bean instances that are not being used at that moment for client requests are subject to passivation. Setting the idle-timeout-seconds parameter has no effect on this rule because the server must make room for additional instances.
  • If bean-managed transaction demarcation is used, a transaction may not be committed or rolled back at the end of a business method call. This leaves the bean instance associated with the transaction, pinned in the cache, and not eligible for passivation. Applications that keep transactions open between stateful session bean calls do not scale well and are difficult to manage.
  • If the cache is full and all instances are currently pinned in the cache fulfilling client requests, WebLogic throws a CacheFullException. It will not block and wait for an instance to become available for passivation. If container-managed transaction demarcation is used, this condition cannot occur if the max-beans-in-cache setting is higher than the maximum number of execute threads and the processing of each client request uses a single stateful session bean.
  • Passivation logic is controlled by the cache-type and idle-timeout-seconds elements in the descriptor. The default setting for cache-type, not recently used (NRU), passivates beans only when the number of active beans approaches the max-beans-in-cache setting. An alternative cache-type value, least recently used (LRU), passivates based on both the maximum cache size and when the bean has not been used for longer than the value of the idle-timeout-seconds setting. The NRU strategy is lazy; the LRU strategy is eager. Although the LRU setting can be a convenient way of enforcing idle timeouts on the resources the objects encapsulate, it requires the container to keep track of the bean’s access time and maintain an ordered list that gets updated after each bean access. Unless you have a good reason to need idle timeouts strictly enforced, most applications should retain the default NRU algorithm.
  • In addition to its role with the LRU cache type, the idle-timeout-seconds property has another purpose. It is the default timeout value for passivated instances, unless the separate session-timeout-seconds property has been set. Passivated instances that have been unused for longer than this timeout are subject to removal from disk storage during cache maintenance. If the container removes an stateful session bean in this way, it does not invoke @PreDestroy or ejbRemove() methods.
  • If the idle-timeout-seconds property is set to zero, beans are simply removed when chosen for passivation and are never passivated to disk storage. This can be a useful option to avoid passivating old instances representing lost clients or transactions that were completed long before. Of course, this can also cause long-running clients to lose their sessions if the max-beans-in-cache is not properly tuned.

Passivation of beans means serialization of non-transient data in the bean to disk storage to release the memory used by the bean. The next request for the passivated bean will require activation, the reverse process, where bean elements are read from the disk store and the active bean instance is recreated in memory. Needless to say, passivation and activation cycles can be extremely expensive. You should monitor the amount of passivation activity occurring in your system using the WebLogic Console and tune the max-beans-in-cache setting to reduce or eliminate this activity to achieve high performance.

Your application should always call a @Remove method to delete the active bean instance from the cache when a client is through using the instance. Failure to call a @Remove method leaves the bean instance in the active state and consumes one slot in the cache, requiring eventual passivation by WebLogic during cache management to make room for additional client beans.

The idle-timeout-seconds setting is very important in cache management. The bean is subject to passivation once the timeout expires, assuming the LRU algorithm is being used, and may be removed from storage completely after the timeout period passes again. The default timeout value, 600 seconds, may be too short if users are likely to pause between requests for a longer period of time. If you are using stateful session beans with a web application, it might make sense to set this timeout value equal to the HttpSession timeout value for your web application, for example, to be more consistent. Otherwise, review your business requirements and set the idle-timeout-seconds to the lowest value possible that still meets your application’s requirements.

EJB Replication

Stateful session bean components are used to encapsulate client-specific data and processes that must maintain state across multiple method invocations. State that is maintained across multiple invocations would be lost if the stateful session bean was deployed to a single server instance that failed or became unavailable to the client. Fortunately, WebLogic provides failover for stateful session beans deployed in a cluster, just as it does for HttpSession data through the use of in-memory replication. Stateful session bean replication is more costly in terms of memory and performance than HttpSession replication because there is no simple way for the container to determine which portions of the bean have changed. Whereas HttpSession replication relies on setAttribute() calls to determine the data that must be sent to the backup server, stateful session bean replication requires before and after images of the stateful session bean to determine changes requiring replication at the end of the transaction. For efficiency, the server keeps the after image from the last transaction to use as the before image for the next; this means that you have two copies of the bean in memory in the primary server and one in the secondary server.

Why would you use replicated stateful session bean components when HttpSession replication fills essentially the same role? Web applications should probably stick with HttpSession replication to maximize performance and avoid introducing additional complexity, but not all applications are web applications. Replicated stateful session bean components allow non-web applications to maintain state between method invocations in a fully clustered fashion as well. Configuring stateful session bean components for in-memory replication requires a replication-type element in the descriptor for the stateless session bean in weblogic-ejb-jar.xml.

<weblogic-enterprise-bean>
	<ejb-name>VideotheekWizard</ejb-name>
	<enable-call-by-reference>True</enable-call-by-reference>
	<jndi-name>ejb/VideotheekWizard</jndi-name>
	<stateful-session-descriptor>
		<stateful-session-clustering>
			<replication-type>InMemory</replication-type>
		</stateful-session-clustering>
	</stateful-session-descriptor>
</weblogic-enterprise-bean>

Message-Driven Beans

Message-driven beans provide a bridge between JMS and EJBs by listening on JMS destinations and invoking EJBs. A number of WebLogic specific features are available to improve the reliability and performance of message-driven beans.

Message-driven beans are pooled in a manner very similar to stateless session beans. The initial and maximum number of message-driven bean instances can be controlled by using the initial-beans-in-free-pool and max-beans-in-free-pool parameters in weblogic-ejb-jar.xml. Unless a custom work manager with a max-threads-constraint is specified using the dispatch-policy, an upper limit of 16 message-driven bean instances is enforced. Limiting the number of instances provides a simple mechanism to throttle the processing of incoming JMS messages. You may wish to do this to match the availability of resources used by an message-driven bean, for example, the number of JDBC connections in a connection pool, or to set the priority of JMS requests versus other synchronous requests. A custom work manager should be used if more precise control is required.

WebLogic supports clustering of JMS destinations and migration of message-driven beans from failed servers to operational servers using administrative functions. Message-driven beans may also be deployed across all servers in a cluster to provide high levels of performance and availability. WebLogic permits message-driven beans to be deployed against third-party JMS providers while retaining proper container-managed transactional behavior. WebLogic achieves this by starting a new transaction, enlisting the remote JMS destination within the transaction, polling for a message, and rolling back the transaction if none is found.

WebLogic can batch multiple calls to onMessage for the receipt of messages in a single container managed transaction. This can improve performance by spreading the cost of the transaction management across multiple onMessage calls. Transaction batching does not require any change to user code; it is enabled by setting the max-messages-in-transaction deployment descriptor element. Because more work is done in a transaction, you may also need to increase the transaction timeout using trans-timeout-seconds. Should the transaction batch fail due to a transaction timeout, WebLogic will temporarily reduce the batch size and resubmit the messages in smaller batches. Should the batch fail due to an onMessage call throwing an exception or marking the transaction for rollback, WebLogic will reprocess each of the messages in an individual transaction.

EJB processing

A high-level understanding of WebLogic’s internal architecture is important to understand how to design, build, deploy, and debug applications that will run on WebLogic. The core components are listen threads, a socket muxer, and an execute queue with associated execute threads. When the server process starts up, it binds to one or more ports and assigns a thread to each port to listen for connection requests. Once the server accepts the connection request and establishes the connection, the server hands off control of the connection to the socket muxer, which waits for incoming requests. At a high level, the socket muxer detects an incoming request, reads the request off of the socket, and places the request along with any associated security or transaction context onto the appropriate execute queue (typically, the self-tuning execute queue). Once a request appears on the execute queue, an idle execute thread takes the request off of the queue, assumes the identity of the user who submitted the request, executes the request, returns the response to the caller, and goes back to wait for the next request.

Once an execute thread invokes the target component of the request, that execute thread will process the entire request. A single execute thread basically spans the servlet, EJB, and JDBC components in the application container, i.e., the call to the servlet, its call to a method on an EJB, and the EJB’s use of JDBC to query a database will all occur within the same execute thread. During the execution of a request, the execute thread will be unavailable to process any other requests until the request processing code completes successfully or throws an exception. This is an extremely important point to recognize. If the application code blocks the execute thread for an extended period of time, the server will not be able to use that thread to process other requests coming into the execute queue. While WebLogic does some basic sanity checks during the execution of any request (for example, checking the transaction timeout before dispatching an EJB method invocation), it is generally not possible for the server to tell the execute thread to abort the processing of a request.

If the application gets into a state where every execute thread is blocked for an extended period of time, the server will either become nonresponsive (for requests targeted to that execute queue) or have to spawn additional execute threads to try to cope with the situation. Although the listen threads and the socket muxer are able to accept new requests from clients and place them into the execute queue, no execute threads will be available to process the request and return the response to the client unless the server is able to spawn new execute threads. Of course, spawning new threads that end up blocking does not improve the overall situation.

When long-running requests cause the execute threads to block, the incoming requests will start to back up in the execute queue. Even if the condition causing the execute threads to block goes away, it is very likely that the execute queue will end up with a relatively large number of messages. This not only will cause degradations in response time but also may cause users to cancel their requests (by clicking the stop button on their browsers) and to resubmit them. Typically, this will only make the situation worse because WebLogic processes every message on the execute queue in first-in-first-out order. In certain conditions (for example, reading HTTP POST data associated with a web application request), WebLogic will detect that the client is no longer waiting for the response and will short-circuit the request processing. Other conditions, though, may cause WebLogic to process the request even if the client is no longer waiting for the response. Fortunately, WebLogic provides a mechanism to limit the number of requests it will accept to prevent this execute queue overload condition.

WebLogic uses a single, priority-based, self-tuning execute queue that increases and decreases the number of execute threads dynamically based on historical performance data. When the server receives a request, it determines the request class to which the request belongs, either implicitly based on the application or explicitly based on an applicable work manager configuration. Using the request class information, the server assigns the request an internal priority and places it on the execute queue, with higher priority requests go closer to the front of the queue. The closer to the front of the queue, the faster the request will be assigned to an execute thread for processing.

WebLogic determines the internal priority of each request using the work managers you create to manage your applications. Work managers provide a way to partition resources across applications. To describe resource partitioning, WebLogic work managers contain four component types:

  1. Request Class
  2. Minimum Threads Constraint
  3. Maximum Threads Constraint
  4. Capacity Constraint

Think of a request class as a mechanism to define the runtime behavior of requests to which it is associated. All requests that share a runtime behavior should share a request class. For example, if all of the HTTP requests within your web applications are equally important, you should associate your web applications with the same request class so that they get equal runtime prioritization when being dispatched by the server. By default, each application belongs to its own request class. WebLogic supports three request class types:

  • Fair Share Request Class – A fair share request class specifies the relative thread usage time of an application as compared to other applications running in the same instance. Imagine a managed server with two applications deployed, A and B. Application A uses a work manager with a fair share of 50 and Application B uses a work manager with a fair share of 150. When the server is receiving a steady stream of requests from both applications that exceed the number of execute threads, the server will assign Application A’s requests to 25% of the available threads and Application B’s requests to 75% of the available threads, assuming that requests for both applications, on average, take the same amount of time to execute. The allowable values of a fair share request class are 1 to 1000. Each application that uses a work manager that does not explicitly reference a request class gets an exclusive fair share value of 50.
  • Response Time Request Class – A response time request class specifies the target response time in milliseconds. Using the previous example, imagine that Application A uses a work manager with a response time of 3000 milliseconds and Application B uses a work manager with a response time of 5000 milliseconds. When the server is receiving a steady stream of requests from both applications that exceed the number of execute threads, the server will keep the average response times of the two applications in a 3 to 5 ratio, where the actual response times will be some fraction or multiple of the response time goal.
  • Context Request Class – A context request class is a compound class that maps between the context of a request and a fair share or response time request class. A context request class supports using authenticated user and group names to map to different fair share or response time request classes. For example, a certain application might assign a higher fair share request class to logged-in users, and all requests associated with the built-in user name ‘anonymous’ to a lower fair share request class.

Constraints allow you to set limits on what a work manager can do. By default, a work manager has no constraints.

The minimum thread constraint has nothing to do with the minimum size of the execute thread pool. Instead, it allows you to ensure that the server will have a certain number of threads available for processing requests associated with work managers using this constraint. This is only useful to prevent deadlocks in certain server-to-server callback scenarios. Imagine that Application A runs on Managed Server 1 and Application B runs on Managed Server 2. If Application A makes an EJB call to Application B and Application B calls back to Application A (or any other application running on Managed Server 1) while processing the EJB call, it is possible to deadlock the two managed servers. If all of Managed Server 1′s threads are waiting on the EJB call’s response, Managed Server 1 will not have any threads available to process the callback requests and the two servers will deadlock waiting on each other. To prevent this deadlock situation, you might assign the callback requests from Application B a higher fair share than the calls generating the EJB calls to Application B. You might also add a minimum threads constraint for the callbacks to ensure that some threads will always be available for processing callbacks.

Maximum thread constraints are useful in a number of situations. For example, if a particular type of request requires a database connection, you might want to set a maximum thread constraint to a value equal to the maximum number of database connections available to your application so that execute threads will not block waiting for a connection to be available. This example is such a common use case that the maximum thread constraint supports either specifying a numeric value or the name of a WebLogic–defined data source. In the latter case, the maximum thread constraint value changes as the maximum size of the data source’s connection pool changes.

Capacity constraints allow you to specify the maximum number of requests a server will accept. The capacity constraint gives you a mechanism to prevent the execute queue overload condition. When determining capacity, the server counts all requests currently executing on an execute thread and all requests waiting in the execute queue. When a capacity constraint is reached, the server takes overload protective action; for example, by returning an HTTP 503 response to indicate that the server is too busy or returning a RemoteException for RMI calls to allow the request to fail over to another server in the cluster. WebLogic also provides a Shared Capacity for Work Managers parameter that limits the total capacity of the server.

During certain types of failure conditions, execute threads may block for extended periods of time waiting for slow backend systems or TCP/IP timeouts in the case of machine or network failures. These conditions can cause execute threads to block for minutes at a time. If the server’s incoming request load is high enough, all available execute threads will be blocked and the server will create more execute threads in an attempt to continue doing useful work. Because the server does not understand the nature of the problem or the applications it is servicing, it cannot make an intelligent decision about whether creating new execute threads will in fact help. The real issue in these situations is that the server is unable to process any requests because of the waiting condition. Your first thought might be to create a maximum thread constraint to prevent the server from creating too many threads; however, this would be treating the symptom and not the root cause. The real problem is that the requests keep piling up in its execute queue. There is no point in the server accepting work if the time it will take to process that work exceeds the time for which the clients are willing to wait on the response. A better way to protect the server in these situations is to define a capacity constraint so that the server starts rejecting work when it is unable to keep up. By combining a capacity constraint with proper tuning of the stuck thread detection capability, you can protect the server from overloading itself during these types of failures.

WebLogic allows you to define work managers, request classes, and constraints at global, application or component levels. Request classes and constraints can either be shared across work managers or be exclusive to a single work manager. All applications share any request classes and constraints associated with their work manager. The only exception to this rule, is for work managers that do not specify a request class and, therefore, use the default fair share request class.

Use the Environment, Work Managers page in the WebLogic Console to define global work managers, request classes, and constraints. All globally-defined request classes and constraints are inherently sharable – whether they are defined within or outside the context of a specific global work manager. For example, if multiple work managers share the same capacity constraint, this means that the sum total of all requests across all work managers sharing the capacity constraint will never exceed the capacity value in each server instance. If multiple applications use the same global work manager that defines an exclusive capacity constraint, this means that the sum total of all requests across all applications sharing the work manager will never exceed the capacity value in each server instance.

WebLogic also supports defining work managers, request classes, and constraints at the application and application component level by adding definitions to weblogic-application.xml, weblogic.xml, or weblogic-ejb-jar.xml. When using deployment descriptors to define request classes and constraints, you have the option to define them inside a specific work manager, for example,

<work-manager>
	<name>VoorbeeldWorkManager</name>
	<response-time-request-class>
		<name>VoorbeeldRequestClass</name>
		<goal-ms>1000</goal-ms>
	</response-time-request-class>
	<max-threads-constraint>
		<name>VoorbeeldConstraint</name>
		<count>100</count>
	</max-threads-constraint>
	<capacity>
		<name>VoorbeeldCapacity</name>
		<count>100</count>
	</capacity>
	<work-manager-shutdown-trigger>
		<max-stuck-thread-time>300</max-stuck-thread-time>
		<stuck-thread-count>5</stuck-thread-count>
	</work-manager-shutdown-trigger>
</work-manager>

WebLogic checks for stuck threads. Stuck threads are threads that have been processing a particular request for more than the configured amount of time. If the server determines that execute threads are stuck, it will take the configured action on the component specifying the stuck thread detection behavior. WebLogic supports configuring stuck thread detection behavior at the server, work manager, and application levels.

If a work manager does not specify a request class, it gets a copy of the default fair share request class whose fair share value is 50. Unlike with explicitly-defined request classes, all applications using a work manager associated with the default fair share request class get their own fair share of 50, rather than sharing the fair share. WebLogic defines a global work manager called default that does not define a request class or any constraints. As such, each application that uses the default work manager will have its own fair share of 50. You can modify the default work manager by creating a global work manager definition with the name default.

To map an EJB to a workmanager, use the dispatch-policy element in the weblogic-ejb-jar.xml file, for example,

<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/90"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-ejb-jar.xsd">
    <weblogic-enterprise-bean>
        <ejb-name>Videotheek</ejb-name>
        <enable-call-by-reference>True</enable-call-by-reference>
        <dispatch-policy>DatabaseWorkManager</dispatch-policy>
        <stateless-session-descriptor>
            <pool>
                <initial-beans-in-free-pool>25</initial-beans-in-free-pool>
                <max-beans-in-free-pool>50</max-beans-in-free-pool>
            </pool>
        </stateless-session-descriptor>
        <transaction-descriptor>
            <trans-timeout-seconds>600</trans-timeout-seconds>
        </transaction-descriptor>
    </weblogic-enterprise-bean>
    <weblogic-enterprise-bean>
        <ejb-name>VideotheekWizard</ejb-name>
        <enable-call-by-reference>True</enable-call-by-reference>
        <dispatch-policy>DatabaseWorkManager</dispatch-policy>
        <stateful-session-descriptor>
            <stateful-session-cache>
                <max-beans-in-cache>50</max-beans-in-cache>
                <idle-timeout-seconds>600</idle-timeout-seconds>
                <session-timeout-seconds>3600</session-timeout-seconds>
                <cache-type>LRU</cache-type>
            </stateful-session-cache>
            <stateful-session-clustering>
                <replication-type>InMemory</replication-type>
            </stateful-session-clustering>
        </stateful-session-descriptor>
    </weblogic-enterprise-bean>
    <weblogic-enterprise-bean>
        <ejb-name>VideotheekMDB</ejb-name>
        <dispatch-policy>MessageWorkManager</dispatch-policy>
        <message-driven-descriptor>
            <pool>
                <initial-beans-in-free-pool>10</initial-beans-in-free-pool>
                <max-beans-in-free-pool>10</max-beans-in-free-pool>
            </pool>
            <destination-jndi-name>jms/VideotheekQueue</destination-jndi-name>
            <jms-polling-interval-seconds>30</jms-polling-interval-seconds>
        </message-driven-descriptor>
    </weblogic-enterprise-bean>
    <work-manager>
        <name>DatabaseWorkManager</name>
        <response-time-request-class>
            <name>DatabaseResponseClass</name>
            <goal-ms>50</goal-ms>
        </response-time-request-class>
        <max-threads-constraint>
            <name>DatabaseMaxThread</name>
            <pool-name>VideotheekDataSource</pool-name>
        </max-threads-constraint>
        <min-threads-constraint>
            <name>DatabaseMinThread</name>
            <count>20</count>
        </min-threads-constraint>
        <capacity>
            <name>DatabaseCapacity</name>
            <count>100</count>
        </capacity>
        <work-manager-shutdown-trigger>
            <max-stuck-thread-time>600</max-stuck-thread-time>
            <stuck-thread-count>10</stuck-thread-count>
        </work-manager-shutdown-trigger>
    </work-manager>
    <work-manager>
        <name>MessageWorkManager</name>
        <response-time-request-class>
            <name>MessageResponseClass</name>
            <goal-ms>100</goal-ms>
        </response-time-request-class>
        <max-threads-constraint>
            <name>MessageMaxThread</name>
            <count>10</count>
        </max-threads-constraint>
        <capacity>
            <name>MessageCapacity</name>
            <count>20</count>
        </capacity>
        <work-manager-shutdown-trigger>
            <max-stuck-thread-time>300</max-stuck-thread-time>
            <stuck-thread-count>5</stuck-thread-count>
        </work-manager-shutdown-trigger>
    </work-manager>
</weblogic-ejb-jar>

The example above also shows how to use the other elements discussed.

References

[1] Patrick, et al., “Professional Oracle WebLogic Server”, Wiley Publishing, Inc., Indianapolis, Indiana, 2010. The first sentence in the introduction of this book goes like this “Professional Oracle WebLogic Server is different from other books about WebLogic Server…”. This book has a good learning value for people who want to understand not just how things can be done, but also want to know the why behind the things that they have done.
[2] Programming Enterprise JavaBeans.
[3] The Java EE Tutorial – Enterprise Beans.


WebLogic WorkManager with EJB3 And MaxThread Constraint

Hi,
Jay SenSharma

Jay SenSharma

WebLogic Provides us a feature to manage the WebLogic Threads per application using WorkManagers. In this demo we will see how we can instruct WebLogic to allocate only one thread to process the Clients request. We will develop a simple EJB3 application and we will assign a WorkManager with MaxThreadConstraint as 2. It means for Any number of Clients request to that EJB, the WebLogic will allocate only 1 Thread for request processing.
.
Step1). Please follow the instructions mentioned in the  link: http://middlewaremagic.com/weblogic/?p=2691 to create WebLogic WorkManager in seconds using WLST. Just make sure that you chose the following values for Max and Min Threads to see how this sample works. Later you can use your own values.
MaxThread=2
MinThread=2
.
Step2). Now create a Directory somewhere in your file system like:  ”C:\temp\EJB3_With_WorkManager”
.
Step3). Now create a EJB remote Interface “CalculatorRemote.java” inside “C:\temp\EJB3_With_WorkManager” like following:
//CalculatorRemote.java
package calculator;
import javax.ejb.*;
@Remote
public interface CalculatorRemote
{
  public int add(int x,int y);
}
Step4). Now ssame way create a Stateless Session Bean “CalculatorBean.java” inside “C:\temp\EJB3_With_WorkManager” like following:
//CalculatorBean.java
package calculator;
import javax.ejb.*;
@Stateless
public class CalculatorBean implements CalculatorRemote
 {
   public int add(int x,int y)
    {
	  System.out.println("Current ThreadName Is: "+Thread.currentThread().getName());
      return (x+y);
    }
 }
Step5). Now create a directory with name “META-INF” inside “C:\temp\EJB3_With_WorkManager” and then create a file “weblogic-ejb-jar.xml”  inside “C:\temp\EJB3_With_WorkManager\META-INF”  directory like following so that we can assign the WebLogic WorkManager to the EJB using “dispatch-policy” tag:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/10.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <weblogic-enterprise-bean>
    <ejb-name>CalculatorBean</ejb-name>
    <stateless-session-descriptor>
      <pool></pool>
      <stateless-clustering>
        <home-is-clusterable>false</home-is-clusterable>
        <stateless-bean-is-clusterable>false</stateless-bean-is-clusterable>
      </stateless-clustering>
    </stateless-session-descriptor>
    <transaction-descriptor></transaction-descriptor>
    <jndi-name>X</jndi-name>
    <dispatch-policy>JackWorkManager</dispatch-policy>
    <remote-client-timeout>0</remote-client-timeout>
  </weblogic-enterprise-bean>
</weblogic-ejb-jar>
Step6). Now run the “setWLSEnv.cmd” in a command prompt to set the classpath then Compile and EJBs and then make a Jar of it like following:
compiling_Ejb3

compiling_Ejb3

Step7). Now deploy the above created EJB3 jar file “Ejb3.jar” in WebLogic Server.
.
Step8). Check the AdminConsole where you are able to see the WorkManager properly assigned to your EJB3 or Not?
 EJB3_Workmanager_Console_look

EJB3_Workmanager_Console_look

Step9). Now Create a Client somewhere in your file system and set the Classpath to Ejb3.jar which we created above…. Client program like following “Ejb3Client.java”.  This client is going to send 5000 fresh requests to the WebLogic Server.
package calculator;
import javax.naming.*;
import java.util.*;
public class  Ejb3Client
{
	public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
	private static String serverUrl ="t3://localhost:7001";
	public static void main(String[] ar)  throws Exception
	{
		for(int i=0;i<=5000;i++)
		 {
           InitialContext ic=null;
           try{
		        Hashtable env = new Hashtable();
		        env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
		        env.put(Context.PROVIDER_URL, serverUrl);
  		        ic = new InitialContext(env);
              }
            catch(Exception e)
             {
			    System.out.println("\n\t Didnot get InitialContext: "+e);
			 }
           try
             {

                Object obj=ic.lookup("calc#calculator.CalculatorRemote");
                CalculatorRemote remote=(CalculatorRemote)obj;
                System.out.println("\n\n\tRemote=>"+remote.getClass());

				System.out.println("\n\n\tClassLoading=>1");
                Class.forName("calculator.CalculatorRemote");
				System.out.println("\n\n\tClassLoading=>2");

                System.out.println("\n\n\t SUM = "+remote.add(Integer.parseInt(ar[0]),Integer.parseInt(ar[1])));
             }
           catch(Exception e)
             {
                System.out.println("\n\n\t jack Exception => "+e);
                e.printStackTrace();
             }
           System.out.println("\n\t Iteration ------------ "+i);
	    }
	}
}
Step10). Run the client and then check the Server STDOUT that all the 5000 request will be processed only by a Two Execute Thread….It means due to MaxThreadConstraint=2 the WebLogic will not allocate more than two thread to process clients request.
EJB3_Workmanager_Client_Console_Output

EJB3_Workmanager_Client_Console_Output

In the output (STDOUT) of the Server you will see that there are only 2 Threads which are processing all the 5000 Clients request…..

Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
.
.
Thanks
Jay SenSharma

Creating WorkManager Using WLST

Hi,

Jay SenSharma

Jay SenSharma

Here we are going to see a very Simple WLST Script to configure the WorkManager with MaxThreadConstraint and MinThreadConstraint and Assigning them to the WorkManager which we created using the same Script.

Step1). Create a Directry some where in your File System like: “C:\WorkManager_WLST”

Step2). Write a Property file with the name “workManagerProperties.properties” inside the “C:\WorkManager_WLST”

adminServerName=AdminServer
ServerName=AdminServer
domainName=base_domain
domainDire=C:/bea103/user_projects/domains/base_domain
host=localhost
protocol=t3
AdminPort=7001
username=weblogic
password=weblogic
MinThread=7
MaxThread=15
workManagerName=MyTestWorkManager
maxThreadConstraintName=MyTestMaxThreadConstraint
minThreadConstraintName=MyTestMinThreadConstraint

Step3). Now write the WLST pythin script “createWorkManager.py” inside “”C:\WorkManager_WLST”" to create the WorkManager like following

import sys
import os
import jarray
import dircache
from java.io import File
from java.lang import String

myPropertyFile = "workManagerProperties.properties"

#=======================================================================================
# connection() Definition
#=======================================================================================
def connection():
	print '===> Connecting as '+ username + ' To WebLogic URL ' + url + '...'
	try:
		connect(username, password, url)
	except WLSTException:
		print '==> Error Connecting to The URL ' + url
		CancelEdit('y')
		exit()

print '==== Exiting Because Of Connectivity Error ===='
#=======================================================================================
print '======= Reading Property File and Connecting to Server ========'
loadProperties(myPropertyFile)
url=protocol + '://' + host + ':' + AdminPort
connection()

edit()
startEdit()
print '======= Creating a WorkManager name as ======='
cd('edit:/SelfTuning/' + domainName + '/WorkManagers/')
create(workManagerName,'WorkManagers')
cd('edit:/SelfTuning/' + domainName + '/WorkManagers/' + workManagerName)
cmo.addTarget(getMBean("/Servers/"+ ServerName))
save()
print ' WorkManager Created...'

print '======= Creating MaxThreadsConstraint ======='
cd('edit:/SelfTuning/' + domainName + '/MaxThreadsConstraints/')
try:
	create(maxThreadConstraintName,'MaxThreadsConstraints')
except Exception:
	print 'Issue in Creating MaxThreads exiting'
cd('edit:/SelfTuning/' + domainName + '/MaxThreadsConstraints/' + maxThreadConstraintName)
cmo.addTarget(getMBean("/Servers/"+ ServerName))
set('Count',MaxThread)
save()

print '======= Creating MinThreadsConstraint ======='
cd('edit:/SelfTuning/' + domainName + '/MinThreadsConstraints/')
try:
	create(minThreadConstraintName,'MinThreadsConstraints')
except Exception:
	print 'Issue In Creating MinThreads '
cd('edit:/SelfTuning/' + domainName + '/MinThreadsConstraints/' + minThreadConstraintName)
cmo.addTarget(getMBean("/Servers/"+ ServerName))
set('Count',MinThread)
save()

print '======= Assigning the MaxThreadConstraint to the WorkManager ======='
cd('edit:/SelfTuning/' + domainName + '/WorkManagers/' + workManagerName)
bean=getMBean('/SelfTuning/' + domainName + '/MaxThreadsConstraints/' + maxThreadConstraintName)
cmo.setMaxThreadsConstraint(bean)

print '======= Assigning the MinThreadConstraint to the WorkManager ======='
cd('edit:/SelfTuning/' + domainName + '/WorkManagers/' + workManagerName)
bean=getMBean('/SelfTuning/' + domainName + '/MinThreadsConstraints/' + minThreadConstraintName)
cmo.setMinThreadsConstraint(bean)

save()
activate(block="true")
print '==> WorkManager Creation Finished ... Please Double Check from AdminConsole...'
disconnect()

Step4). Open a Command Window and then run the “setWLSEn.cmd” (for windows)… or “setWLSEnv.sh” (for Unix Based OS) Then run the WLST Script :
NOTE: Run the setWLSEnv.sh always with preseeding two DOTs like
“. ./setWLSEnv.sh”
The first DOT represents that set the Environment in the current Shell, AND the second ./ represents execute the script from the current directory.

running the setWLSEnv.cmd to set CLASSPATH/PATH

running the setWLSEnv.cmd to set CLASSPATH/PATH

java weblogic.WLST createWorkManager.py workManagerProperties.properties

Running the WLST Script to Create WorkManager

Running the WLST Script to Create WorkManager

Step5). Double check the AdminConsole that everything looks good?

Admin Console After Creation of WorkManager

Admin Console After Creation of WorkManager

.
.
Thanks
Jay SenSharma


Adding WorkManager Using Plan.xml to a WAR file

Hi,

Jay SenSharma

Jay SenSharma

Suppose if you already have deployed your WebApplication (WAR) file on the Server …this time if you hit your Application then in AdminConsole you will see that the requests are being processed by the “default” workManager.

To see this you can login to your applications workmanager status ….
AdminConsole—>Deployments—.YourWebApplication—>Monitoring (TAB)—>workload (Sub tab)
.
Here you will see that as soon as you hit your webapplication it’s request is being served by the “default” work manager. You don’t want to Change your WebApplication by adding <wl-dispatch-policy> tag inside your “weblogic.xml”. So this can be done by using “Plan.xml”…using this file we will assign WorkManager Dynamically to an existing application without physically touching the actual application.
.
NOTE: Please make sure that atleast on “weblogic.xml” is already available inside your WebApplication which uses WLS9.x onwards schema defination…like following… If you already have weblogic.xml inside your WAR then it’s good…or else please add the following empty “weblogic.xml” inside your WebApp…
<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<weblogic-web-app xmlns=”http://www.bea.com/ns/weblogic/90″>
</weblogic-web-app>

.
Step1). Create a WorkManager through AdminConsole with the following configuration:
with the following Configuration: in your “config.xml”…or define your Workmanager according to your requirement
<self-tuning>
<context-request-class>
<name>ContextReqClass-0</name>
<target>AdminServer</target>
</context-request-class>
<min-threads-constraint>
<name>MyMaxConstraint</name>
<target>AdminServer</target>
<count>1</count>
</min-threads-constraint>
<capacity>
<name>CapacityConstraint-0</name>
<target>AdminServer</target>
<count>1</count>
</capacity>
<work-manager>
<name>myConsoleWorkManager</name>
<target>AdminServer</target>
<context-request-class>ContextReqClass-0</context-request-class>
<min-threads-constraint>MyMaxConstraint</min-threads-constraint>
<capacity>CapacityConstraint-0</capacity>
</work-manager>
</self-tuning>
Note: After configuring the above workManager we need to restart the Server…As a Best practice.
.
.
Step2). Open a Command window or a Shell prompt and then run “. ./setWLSEnv.sh” or “setDomainEnv.sh” to set the environment in that shell.
.
.
Step3). In the Shell prompt Move till the your WAR file…Lets say your WAR filename is “MyWorkManagerDemo.war”. which is placed inside
“/opt/apps” directory then first do
cd /opt/apps
.
.
Step4). Now run the “weblogic.PlanGenerator” utility to generate the Plan.xml file in the current Directory. Like following:
java weblogic.PlanGenerator -all MyWorkManagerDemo.war
OUTPUT:
Generating plan for application MyWorkManagerDemo.war
Export option is: all
Exporting properties…
Saving plan to /opt/apps/plan.xml…
<Mar 14, 2010 2:57:00 PM IST> <Info> <J2EE Deployment SPI> <BEA-260072> <Saved configuration for application, MyWorkManagerDemo>
.
.
Step5). Now the generated “plan.xml” file will be bit large …we need to edit it…
.
.
Step6). Edit it like:
You will find <variable-definition> with many sub tags like <variable>   Just edit one of them and delete rest of the <variable> Tags
you can give any name to the variable like “firstVariableName”.
Now edit the next line <value xsi:nil=”true”></value>  by removing the  xsi:nil=”true” from this Tag….means you need to change it to and then add your WorkManager name there like:
<value>myConsoleWorkManager</value>
Now edit the Module which you want to override: <module-override> and then assign the Variable there and <config-root> tag pointing to the Plan.xml directory…Finally you will get a “plan.xml” file like following:
<?xml version='1.0' encoding='UTF-8'?>
<deployment-plan xmlns="http://www.bea.com/ns/weblogic/deployment-plan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/deployment-plan http://www.bea.com/ns/weblogic/deployment-plan/1.0/deployment-plan.xsd" global-variables="false">
<application-name>MyWorkManagerDemo.war</application-name>
<variable-definition>
<variable>
<name>firstVariableName</name>
<value>myConsoleWorkManager</value>
</variable>
</variable-definition>
<module-override>
<module-name>MyWorkManagerDemo</module-name>
<module-type>war</module-type>
<module-descriptor external="true">
<root-element>weblogic-web-app</root-element>
<uri>WEB-INF/weblogic.xml</uri>
<variable-assignment>
<name>firstVariableName</name>
<xpath>/weblogic-web-app/wl-dispatch-policy</xpath>
</variable-assignment>
</module-descriptor>
</module-override>
<config-root>/opt/apps/</config-root>
</deployment-plan>
.
.
Step7). Now Login to AdminConsole then Update your Application …while updating your Application it will ask for the “plan.xml” file Location…just browse for this file… While updating your WebApplication with “plan.xml” file please choose the following radio button in the AdminConsole:
“Redeploy this application using the following deployment files” FINISH
.
.
Step8). Now hit your application …you will see in the “workload” Subtab of your application then it is being processed by the “myConsoleWorkManager” which is created by us.
.
.
.
Thanks
Jay SenSharma

WorkManager At WebApplication Level

Hi,

Jay SenSharma

Jay SenSharma

If you want to Assign a Global Work Manager (A Work Manager which is created through AdminConsole).. And if you want more than 1-Thread should not be allocated by the WebLogic to process request for your WebApplication…then you can do the Following:

Provide the Capacity-Constraint to 1

Step1). Configure a WorkManager from Admin Console.

with the following Configuration: in your “config.xml”

<self-tuning>
<context-request-class>
<name>ContextReqClass-0</name>
<target>AdminServer</target>
</context-request-class>

<min-threads-constraint>
<name>MyMaxConstraint</name>
<target>AdminServer</target>
<count>1</count>
</min-threads-constraint>

<capacity>
<name>CapacityConstraint-0</name>
<target>AdminServer</target>
<count>1</count>
</capacity>

<work-manager>
<name>myConsoleWorkManager</name>
<target>AdminServer</target>
<context-request-class>ContextReqClass-0</context-request-class>
<min-threads-constraint>MyMaxConstraint</min-threads-constraint>
<capacity>CapacityConstraint-0</capacity>
</work-manager>

</self-tuning>
Note: After configuring the above workManager we need to restart the Server…
Step2). Write a Simple WebApplication with the following kind of JSP Page:
<%@ page import="java.util.*" %>
<%!
static int counter=0;
%>
<%
session.setAttribute("counter","Counter-"+counter);
counter++;
for(int id=0;id<60;id++)
{
System.out.println(id+"\tRequest Is Being Processsed for :"+(String)session.getAttribute("counter"));
try{
Thread.sleep(1000);
}
catch(Exception e)
{
e.printStackTrace();
}
}
out.println("<h2>Request Processing Completed");
%>
Step3). Now provide the “weblogic.xml” bu providing the Work-Manager name in wl-dispatch-policy annotation:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90">
<wl-dispatch-policy>myConsoleWorkManager</wl-dispatch-policy>
</weblogic-web-app>
Step4). Now deploy the Application and And
you can check it from admin console as well..

AdminConsole–> Home–>Deployment Summary–> (click on your WebApp)–>Monitoring (Tab)—> WorkLoad (Sub-Tab)

Hit your WebApplication and then See …in admin Console…How many request is being processed…

When you send the Concurrent Second request to the WebApplication you will get 503-Service Not Available Error By the WebLogic Server…Because of the Constraint Capicity=1 …weblogic will process only 1 Concurrent request for your WebApplication.

.

.

Thanks

Jay SenSharma



Application Level WorkManager & TimerManager Lookup

Hi,

Jay SenSharma

Jay SenSharma

Most of the time we have observed that many WebLogic Developers and Admins face various issues while configuring and looking up the Application Level WorkManager.

WebLogic Server prioritizes work and allocates threads based on an execution model that takes into account administrator-defined parameters and actual run-time performance and throughput.

Work Managers can be configured at the domain level, application level, and module level in one of the following configuration files:

  • config.xml—Work Managers specified in config.xml can be assigned to any application, or application component, in the domain. You can use the Administration Console to define a Work Manager.
  • weblogic-application.xml—Work Managers specified at the application level can be assigned to that application, or any component of that application.
  • weblogic-ejb-jar.xml or weblogic.xml—Work Managers specified at the component-level can be assigned to that component.
  • weblogic.xml—Work Managers specified for a Web Application.

Here is a Simplest sample we are going to develop…to see how to utilize the Application level Work Managers. It means we need NOT to configure any WorkManager using Admin Console…It will be configured through Deployment Descriptor.

Step1). First of all we will develop the “index.jsp” page to see how to lookup the “commonj.work.WorkManager” and the TimerManager which we are going to configure …

<%@ page import="javax.naming.InitialContext,commonj.timers.TimerManager" %>
<%
System.out.println("\n\n\t ---------------1-------------");
TimerManager timerManager = null;
try {
InitialContext initContext = new InitialContext();
timerManager = (TimerManager) initContext.lookup("java:comp/env/timer/TestTimer");
System.out.println("\n\n\t I am able to Lookup: "+timerManager);
out.println("<b><font color=GREEN>\"timer/TestTimer\" Created Using DD</font> I am able to Lookup:</b>"+timerManager);
}
catch (Throwable anException)
{
throw new RuntimeException(anException);
}
System.out.println("\n\n\t ---------------2-------------");
try {
InitialContext initContext2 = new InitialContext();
commonj.work.WorkManager workManager = (commonj.work.WorkManager)initContext2.lookup("java:comp/env/wm/WorkManagerA");
System.out.println("\n\n\t I am able to Lookup: commonj.work.WorkManager workManager = "+workManager);
out.println("<BR><BR><BR><b><font color=red>Application Level Work Manager.</font>  I am able to Lookup:</b> "+workManager);
}
catch (Throwable anException)
{
System.out.println("\n\n\t Exception Thrown: "+anException);
throw new RuntimeException(anException);
}
System.out.println("\n\n\t ---------------3-------------");
%>

Step2). Now we will develope the “web.xml” here we will provide the reference to the WorkManager and the TimerManager resource -ref

<web-app xmlns="http://java.sun.com/xml/ns/j2ee">
   <resource-ref>
        <res-ref-name>timer/TestTimer</res-ref-name>
        <res-type>commonj.timers.TimerManager</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
  </resource-ref>

  <resource-ref>
        <res-ref-name>wm/WorkManagerA</res-ref-name>
        <res-type>commonj.work.WorkManager</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
        </resource-ref>
</web-app>
Step 3). Now we need to define the <work-manager>  tag in “weblogic.xml” file…
<?xml version="1.0" encoding="ISO-8859-1"?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90">
    <work-manager>
       <name>WorkManagerA</name>
       <max-threads-constraint>
          <name>MyMaxThreadCount_2</name>
          <count>2</count>
       </max-threads-constraint>
    </work-manager>
    <wl-dispatch-policy>WorkManagerA</wl-dispatch-policy>
</weblogic-web-app>
Step 4). Now we need to Deploy this Application in WebLogic Server then We will find …Now Login to Admin Console here in “Home—>Deployments—>WorkManagerDemoApp—>Configuration(Tab)—>WorkLoad(Tab)” we can see that WorkManagerA is configured as soon as the deployment was Successful…

.
.
Thanks
Jay SenSharma


  • Testimonials

  • RSS Middleware Magic – JBoss

  • Receive FREE Updates


    FREE Email updates of our new posts Enter your email address:



  • Magic Archives

  • Sitemeter Status

  • ClusterMap 7-Nov-2011 till Date

  • ClusterMap 6-Nov-2010 till 7-Nov-2011

  • Copyright © 2010-2012 Middleware Magic. All rights reserved. | Disclaimer