Saturday, March 31, 2012

Weblogic login module test - Firefox plugin to modify HTTP request header (also possible with Opera cookie editor)

Modify Headers Firefox plugin
https://addons.mozilla.org/en-US/firefox/addon/modify-headers/


Modify HTTP header


Capture HTTP headers




Weblogic Identity Assertion Concepts
http://docs.oracle.com/cd/E21764_01/web.1111/e13718/ia.htm#autoId0

Weblogic log of test Identity Asserter
SimpleSampleIdentityAsserterProviderImpl.assertIdentity
Type = SamplePerimeterAtnToken
Token = [B@f99f26
userName = dave



weblogic.xml assigns role to group
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee"
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-web-app.xsd">

<security-role-assignment>
<role-name>SamplePerimeterAtnRole</role-name>
<principal-name>SamplePerimeterAtnUsers</principal-name>
</security-role-assignment>

</weblogic-web-app>


web.xml configures web resource as secured
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<!-- Specifies the security settings for the SamplePerimeterAtn web app.

This webapp is used to demonstrate how to use identity assertion to
perform perimeter authentication (where someone outside WLS is
responsible for authenticating the user).

Copyright (c) 2005 by BEA Systems, Inc. All Rights Reserved.
-->

<security-constraint>

<!-- all the pages in this webapp are secured -->
<web-resource-collection>
<web-resource-name>SecuredPages</web-resource-name>
<url-pattern>/</url-pattern>
</web-resource-collection>

<!-- only users in the SamplePerimeterAtnRole will
be granted access to the pages in this webapp
-->
<auth-constraint>
<role-name>
SamplePerimeterAtnRole
</role-name>
</auth-constraint>

<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>

</security-constraint>

<!-- Use weblogic.xml to map the SamplePerimeterAtnRole
to the SamplePerimeterAtnUsers group. As a result,
"SamplePerimterAtnUsers" will be granted the role
for this webapp (thus be able to access its pages)
-->
<security-role>
<role-name>
SamplePerimeterAtnRole
</role-name>
</security-role>

<!-- turn on identity assertion

The webapp only specifies that identity assertion should be
used. It does not dictate what kind of tokens to use. Rather,
the client and the identity asserter have to agree on the token
type and format.

- the client is responsible sending in a token that identifies the user

- the identity asserter is responsible for converting that token
to a user name.

- the authenticators are responsible for putting that user
and its groups into the subject

The realm name is not used so set it to "NoSuchRealm". It
has nothing to do with the realm names in the console.

Set the auth method to CLIENT-CERT to turn on identity
assertion for this webapp.
-->
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>NoSuchRealm</realm-name>
</login-config>

</web-app>




Error without modified header

Error 401--Unauthorized
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.46) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity MAY include relevant diagnostic information. HTTP access authentication is explained in section 11.



Result page with added header
SamplePerimeterAtn.jsp Subject: Principal: dave Principal: SamplePerimeterAtnUsers Private Credential: dave 


Authorized access with configured Identity Asserter


Modify SimpleSampleIdentityAsserter - set Base64DecodingRequired to false
http://docs.oracle.com/cd/E21764_01/web.1111/e13718/ia.htm#autoId15

 
<MBeanAttribute
Name = "Base64DecodingRequired"
Type = "boolean"
Writeable = "false"
Default = "false"
Description = "See MyIdentityAsserter-doc.xml."
/>


Capture HTTP headers
http://localhost:7001/samplePerimeterAtnWebApp/SamplePerimeterAtn.jsp

GET /samplePerimeterAtnWebApp/SamplePerimeterAtn.jsp HTTP/1.1
Host: localhost:7001
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: ADMINCONSOLESESSION=0X41P3rh1pbcCGhBn8nJ5yB55R9zds3v6fjD68QMjT5F6cYZqFGJ!-863651884; JSESSIONID=WVJXP3rJnc1tpjTn5SHW4TC5tRLGhgDBgBDTvZqTQGSR67r88XDR!-863651884
SamplePerimeterAtnToken: username=dave

HTTP/1.1 200 OK
Date: Sat, 31 Mar 2012 16:17:46 GMT
Content-Length: 116
Content-Type: text/html; charset=ISO-8859-1
X-Powered-By: Servlet/3.0 JSP/2.2



To change user it is necessary to remove cookie with JSESSIONID

Cookie: JSESSIONID=pZrFP3yQQpFLnJvPLGSTpcgnGRqCQtYJfdfpySLYJG1gd3QCTGWz!-863651884


In Firefox this is done using about:permissions


Opera allows to edit existing cookies
Cookie Information


Cookie Manager



IdentityAsserter MBean in WLS Admin console


All Weblogic users are assigned to group users. This can be used to allow access to authorized application for all authenticated users by mapping role to users principal in web.xml


 weblogic.security.Security.getCurrentSubject()


returns
SamplePerimeterAtn.jsp Subject: Principal: dave Private Credential: dave 



weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee"
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-web-app.xsd">

<security-role-assignment>
<role-name>authusers</role-name>
<principal-name>users</principal-name>
</security-role-assignment>

</weblogic-web-app>



web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<!-- Specifies the security settings for the SamplePerimeterAtn web app.

This webapp is used to demonstrate how to use identity assertion to
perform perimeter authentication (where someone outside WLS is
responsible for authenticating the user).

Copyright (c) 2005 by BEA Systems, Inc. All Rights Reserved.
-->

<security-constraint>

<!-- all the pages in this webapp are secured -->
<web-resource-collection>
<web-resource-name>SecuredPages</web-resource-name>
<url-pattern>/</url-pattern>
</web-resource-collection>

<!-- all authenticated users in the authusers will
be granted access to the pages in this webapp
-->
<auth-constraint>
<role-name>authusers</role-name>
</auth-constraint>

<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>

</security-constraint>

<!-- Use weblogic.xml to map the authusers
to the users group. As a result,
"users" will be granted the role
for this webapp (thus be able to access its pages)
-->
<security-role>
<role-name>
authusers
</role-name>
</security-role>

<!-- turn on identity assertion

The webapp only specifies that identity assertion should be
used. It does not dictate what kind of tokens to use. Rather,
the client and the identity asserter have to agree on the token
type and format.

- the client is responsible sending in a token that identifies the user

- the identity asserter is responsible for converting that token
to a user name.

- the authenticators are responsible for putting that user
and its groups into the subject

The realm name is not used so set it to "NoSuchRealm". It
has nothing to do with the realm names in the console.

Set the auth method to CLIENT-CERT to turn on identity
assertion for this webapp.
-->
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>NoSuchRealm</realm-name>
</login-config>

<servlet>
<description></description>
<display-name>AuthenticationSnoop</display-name>
<servlet-name>AuthenticationSnoop</servlet-name>
<servlet-class>dave.AuthenticationSnoop</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AuthenticationSnoop</servlet-name>
<url-pattern>/AuthenticationSnoop</url-pattern>
</servlet-mapping>

</web-app>

Sunday, March 11, 2012

Profile with jvisualvm

http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/

http://docs.oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html

Here is how to configure Eclipse IDE launcher
http://visualvm.java.net/eclipse-launcher.html


jvisualvm is part of JDK
[dave@dave ~]$ cd /app/jdk160_29/bin
[dave@dave bin]$ ls
appletviewer java jcontrol jstack policytool unpack200
apt javac jdb jstat rmic wsgen
ControlPanel javadoc jhat jstatd rmid wsimport
extcheck javah jinfo jvisualvm rmiregistry xjc
HtmlConverter javap jmap keytool schemagen
idlj java-rmi.cgi jps native2ascii serialver
jar javaws jrunscript orbd servertool
jarsigner jconsole jsadebugd pack200 tnameserv



Simple program comparing methods to create large string
package dave;

public class StringService {

int STRING_COUNT = 10000;

public String createString(String token) {

String out = "";

for (int i = 0; i < 1000; i++) {
out += token;
}

return out;

}

public String createStringWithStringBuffer(String token) {

StringBuffer out = new StringBuffer();

for (int i = 0; i < STRING_COUNT; i++) {
out.append(token);
}

return out.toString();
}

public String createStringWithStringBuilder(String token) {

StringBuilder out = new StringBuilder();

for (int i = 0; i < STRING_COUNT; i++) {
out.append(token);
}

return out.toString();

}

}




package dave;

public class TestProfiler {

public static void main(String[] args) {

String token = "dave";

StringService stringService = new StringService();

String result = null;

for (int i = 0; i < 10000; i++) {

result = stringService.createString(token);

result = stringService.createStringWithStringBuffer(token);

result = stringService.createStringWithStringBuilder(token);
}

}

}





Profiler with settings to select package


Sampler

Sunday, March 4, 2012

Monitoring with jconsole

Managing WebLogic servers with JConsole
https://blogs.oracle.com/WebLogicServer/entry/managing_weblogic_servers_with

Java Management Extensions (JMX)
http://docs.oracle.com/javase/6/docs/technotes/guides/jmx/index.html

Tutorial: Java Management Extensions (JMX)
http://docs.oracle.com/javase/tutorial/jmx/TOC.html

jconsole usage
Usage: jconsole [ -interval=n ] [ -notile ] [ -pluginpath <path> ] [ -version ] [ connection ... ]

-interval Set the update interval to n seconds (default is 4 seconds)
-notile Do not tile windows initially (for two or more connections)
-pluginpath Specify the path that jconsole uses to look up the plugins
-version Print program version

connection = pid || host:port || JMX URL (service:jmx:<protocol>://...)
pid The process id of a target process
host A remote host name or IP address
port The port number for the remote connection

-J Specify the input arguments to the Java virtual machine
on which jconsole is running



Command line
[dave@dave app]$ jconsole -J-Djava.class.path=$JAVA_HOME/lib/jconsole.jar:$JAVA_HOME/lib/tools.jar:$WL_HOME/server/lib/wlfulclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug



Plan task FibonacciTask 94
Plan task FibonacciTask 95
Plan task FibonacciTask 96
Plan task FibonacciTask 97
Plan task FibonacciTask 98
Plan task FibonacciTask 99
wm.waitForAll
## [FibWork][ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 36
## [FibWork][ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 38
## [FibWork][ACTIVE] ExecuteThread: '11' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 39
## [FibWork][ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 40
## [FibWork][ACTIVE] ExecuteThread: '7' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 41
## [FibWork][ACTIVE] ExecuteThread: '15' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 42
## [FibWork][ACTIVE] ExecuteThread: '22' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 43
## [FibWork][ACTIVE] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 44
## [FibWork][ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 45
## [FibWork][ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 46
## [FibWork][ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 47
## [FibWork][ACTIVE] ExecuteThread: '11' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 48
## [FibWork][ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 49
## [FibWork][ACTIVE] ExecuteThread: '7' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 50
## [FibWork][ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 51
## [FibWork][ACTIVE] ExecuteThread: '15' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 52



Thread dump
Name: [ACTIVE] ExecuteThread: '11' for queue: 'weblogic.kernel.Default (self-tuning)'
State: RUNNABLE
Total blocked: 98 Total waited: 120

Stack trace:
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.fibonacci(FibonacciTask.java:19)
dave.FibonacciTask.run(FibonacciTask.java:13)
dave.FibWork.run(FibWork.java:29)
weblogic.work.j2ee.J2EEWorkManager$WorkWithListener.run(J2EEWorkManager.java:184)
weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
weblogic.work.ExecuteThread.run(ExecuteThread.java:221)


Processes
op - 08:37:09 up 10:55, 10 users,  load average: 10.68, 9.80, 5.91
Tasks: 177 total, 1 running, 176 sleeping, 0 stopped, 0 zombie
Cpu(s): 96.1%us, 3.9%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1533932k total, 1411044k used, 122888k free, 13200k buffers
Swap: 2514100k total, 76348k used, 2437752k free, 369768k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4219 dave 20 0 902m 235m 16m S 171.1 15.7 25:34.98 java
1951 dave 9 -11 160m 4832 4116 S 8.5 0.3 6:55.87 pulseaudio
3824 dave 20 0 530m 208m 24m S 6.2 13.9 6:08.51 firefox
3856 dave 20 0 317m 68m 11m S 6.2 4.6 7:35.17 plugin-containe
4273 dave 20 0 494m 139m 19m S 3.3 9.3 1:03.21 jconsole
1633 root 20 0 137m 22m 14m S 2.6 1.5 9:10.48 Xorg
2402 dave 20 0 124m 13m 9328 S 2.0 0.9 1:02.39 gnome-terminal
1155 root 20 0 0 0 0 S 0.3 0.0 0:34.19 kondemand/0
4337 dave 20 0 1001m 327m 29m S 0.3 21.9 1:14.09 eclipse
4575 dave 20 0 2728 1012 756 R 0.3 0.1 0:00.23 top
1 root 20 0 2888 1032 916 S 0.0 0.1 0:01.66 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:01.20 ksoftirqd/0
4 root RT 0 0 0 0 S 0.0 0.0 0:00.90 migration/0
5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
6 root RT 0 0 0 0 S 0.0 0.0 0:01.11 migration/1
7 root 20 0 0 0 0 S 0.0 0.0 0:00.86 ksoftirqd/1



Stuck thread
<Mar 4, 2012 8:39:35 AM CET> <Error> <WebLogicServer> <BEA-000337> <[STUCK] ExecuteThread: '11' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "717" seconds working on the request "Workmanager: daveWM, Version: 1, Scheduled=true, Started=true, Started time: 717593 ms
", which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace:



JVM overview


Application attributes


Weblogic process threads

Saturday, March 3, 2012

Schedule jobs with WorkManager

Leveraging EJB Timers for J2EE Concurrency
http://www.devx.com/Java/Article/33694/1954

The Work Manager API: Parallel Processing Within a J2EE Container
http://www.devx.com/Java/Article/28815/0


Using Work Managers to Optimize Scheduled Work
http://docs.oracle.com/cd/E14571_01/web.1111/e13701/self_tuned.htm#CNFGD112

Using CommonJ With WebLogic Server
http://docs.oracle.com/cd/E14571_01/web.1111/e13701/self_tuned.htm#i1069944


JBoss WorkManagerTaskExecutor
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/scheduling/commonj/WorkManagerTaskExecutor.html

Package commonj.work

http://docs.oracle.com/cd/E14571_01/apirefs.1111/e13941/commonj/work/package-summary.html

commonj.work.WorkManager

The WorkManager is the abstraction for dispatching and monitoring asynchronous work and is a factory for creating application short or long lived Works.

WorkManagers are created by the server administrator. The vendor specific systems management console allows the administrator to create one or more WorkManagers and associate a JNDI name with each one. The administrator may specify implementation specific information such as min/max Works for each WorkManager. An application that requires a WorkManager should declare a resource-ref in the EJB or webapp that needs the WorkManager. The vendor descriptor editor or J2EE IDE can be used to bind this resource-ref to a physical WorkManager at deploy or development time. An EJB or servlet can then get a reference to a WorkManager by looking up the resource-ref name in JNDI and then casting it. For example, if the resource-ref was called wm/WorkManager:
 <resource-ref>
<res-ref-name>wm/WorkManager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>


The Java code to look this up would look like:
  InitialContext ic = new InitialContext();
WorkManager wm = (WorkManager)ic.lookup("java:comp/env/wm/WorkManager");


The res-auth and res-sharing scopes are ignored in this version of the specification. The EJB or servlet can then use the WorkManager as it needs to.
When a Work is scheduled, the declared context that is present on the thread (the J2EE context) will be saved and propagated to the asynchronous methods that are executed. This J2EE context at minimum will contain the java:comp namespace and ClassLoader of the scheduler unless specified otherwise. Other J2EE contexts such as security or a transactional context may be optionally added by the application server vendor. Global transactions are always available using the java:comp/UserTransaction JNDI name and are used in the same fashion as they are used in servlets and bean-managed transaction Enterprise Java Beans.

A WorkManager can also be a pinned WorkManager. This is a WorkManager obtained using the RemoteWorkItem.getWorkManager method. This allows subsequent scheduleWorks to be send to the same remote WorkManager as the one that is associated with the RemoteWorkItem. Pinned WorkManagers are only supported on vendor implementations that support remote Works. However, applications that follow the programming model will work on all implementations however serializable Works will be executed within the local JVM only on those implementations.

If the scheduled Work is a daemon Work, then the life-cycle of that Work is tied to the application that scheduled it. If the application is stopped, the Work.release() method will be called.


Using the Job Scheduler
http://docs.oracle.com/cd/E14571_01/web.1111/e13733/toc.htm#i1058048

WorkManagerService
package dave;

import java.util.Collection;

import javax.ejb.Remote;

@Remote
public interface WorkManagerService {

public void processJob();

public void processTask(Task task);

public Collection<Task> processTasks(Collection<Task> tasks);

}




CommonJWorkManager
package dave;

import java.util.ArrayList;
import java.util.Collection;

import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import weblogic.work.ExecuteThread;

import commonj.work.Work;
import commonj.work.WorkEvent;
import commonj.work.WorkException;
import commonj.work.WorkItem;
import commonj.work.WorkManager;

/**
* Session Bean implementation class CommonJWorkManager
*/
@Stateless(mappedName = "WorkManagerService")
@LocalBean
public class CommonJWorkManager implements WorkManagerService {

@Resource(name = "daveWM")
WorkManager wm;

/**
* Default constructor.
*/
public CommonJWorkManager() {
// TODO Auto-generated constructor stub
}

public void processJob() {

try {
System.out.println("## [CommonJWorkManager] executing in: "
+ ((ExecuteThread) Thread.currentThread()).getWorkManager()
.getName());
wm.schedule(new Work() {
public void run() {
ExecuteThread th = (ExecuteThread) Thread.currentThread();
System.out
.println("## [CommonJWorkManager] self-tuning workmanager: "
+ th.getWorkManager().getName());
}

public void release() {
}

public boolean isDaemon() {
return false;
}
});

} catch (WorkException e) {
e.printStackTrace();
}

}

public void processTask(Task task) {

System.out.println("Plan task " + task.getName());

try {
System.out.println("## [CommonJWorkManager] executing in: "
+ ((ExecuteThread) Thread.currentThread()).getWorkManager()
.getName());

wm.schedule(new FibWork(task));

} catch (WorkException e) {
e.printStackTrace();
}

}

@Override
public Collection<Task> processTasks(Collection<Task> tasks) {

Collection<WorkItem> workItems = new ArrayList<WorkItem>();
Collection<Task> out = new ArrayList<Task>();

try {
System.out.println("## [CommonJWorkManager] executing in: "
+ ((ExecuteThread) Thread.currentThread()).getWorkManager()
.getName());

for (Task task : tasks) {
System.out.println("Plan task " + task.getName());
WorkItem workItem = wm.schedule(new FibWork(task));
workItems.add(workItem);
}
System.out.println("wm.waitForAll");
wm.waitForAll(workItems, 60000);
for (WorkItem workItem : workItems) {
System.out.println("workItem.result=" + workItem.getStatus());
if (workItem.getStatus() == WorkEvent.WORK_COMPLETED
|| workItem.getStatus() == WorkEvent.WORK_REJECTED) {
FibWork work = (FibWork) workItem.getResult();
if (work != null) {
out.add(work.getTask());
System.out.println("workItem task"
+ work.getTask().getName() + " result="
+ ((FibonacciTask) work.getTask()).getResult());
}
}
}

} catch (WorkException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

return out;

}

}



FibWork
package dave;

import weblogic.work.ExecuteThread;
import commonj.work.Work;

public class FibWork implements Work {

Task task;

public Task getTask() {
return task;
}

public void setTask(Task task) {
this.task = task;
}

public FibWork(Task task) {
this.task = task;
}

@Override
public void run() {

ExecuteThread th = (ExecuteThread) Thread.currentThread();
System.out.println("## [FibWork] self-tuning workmanager: "
+ th.getWorkManager().getName());
System.out.println("Running task " + task.getName());
task.run();

}

@Override
public boolean isDaemon() {
return false;
}

@Override
public void release() {
// TODO Auto-generated method stub

}

}



FibonacciCalculatorBean
package dave;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

/**
* Session Bean implementation class FibonacciCalculatorBean
*/
@Stateless(mappedName = "FibonacciCalculator")
public class FibonacciCalculatorBean implements FibonacciCalculator {

@EJB(mappedName = "WorkManagerService")
private WorkManagerService workManagerService;


public void calculateFibonacci(int[] numbers) {
long initialTime = System.currentTimeMillis();
List<Task> tasks = new ArrayList<Task>();
for (int i = 1; i < numbers.length; i++){
FibonacciTask fibonacciTask = new FibonacciTask(numbers[i]);
tasks.add(fibonacciTask);
}
Collection<Task> resultTasks = workManagerService.processTasks(tasks);
long elapsedTime = System.currentTimeMillis() - initialTime;
printFibonacciResults(resultTasks, elapsedTime);
}

private void printFibonacciResults(Collection<Task> tasks, long elapsedTime) {
System.out.println("** Completed Fibonacci Computations in " + elapsedTime
+ "ms **");
for (Task task : tasks) {
FibonacciTask ft = (FibonacciTask) task;
System.out.println("Fibonacci(" + ft.getN() + ") = " + ft.getResult());
}
}

}



weblogic-ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-ejb-jar xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd http://xmlns.oracle.com/weblogic/weblogic-ejb-jar http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.3/weblogic-ejb-jar.xsd">
<!--weblogic-version:12.1.1-->
<wls:weblogic-enterprise-bean>
<wls:ejb-name>CommonJWorkManager</wls:ejb-name>
<wls:stateless-session-descriptor></wls:stateless-session-descriptor>
<wls:transaction-descriptor>
<wls:trans-timeout-seconds>300</wls:trans-timeout-seconds>
</wls:transaction-descriptor>
<wls:dispatch-policy>daveWM</wls:dispatch-policy>
</wls:weblogic-enterprise-bean>

<wls:work-manager>
<wls:name>daveWM</wls:name>

<wls:max-threads-constraint>
<wls:name>MaxThreadsCountTen</wls:name>
<wls:count>10</wls:count>
</wls:max-threads-constraint>
</wls:work-manager>
</wls:weblogic-ejb-jar>


Client
package dave;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;

public class FibonacciClient {

public static void main(String[] args)

{
try

{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "weblogic123");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(env);
System.out.println("Initial Context created");

/*TimerSession timerSession = (TimerSession) ctx
.lookup("TimerSession#dave.TimerSession");
timerSession.createTimer(100000);*/

FibonacciCalculator fibonacciCalculator = (FibonacciCalculator) ctx
.lookup("FibonacciCalculator#dave.FibonacciCalculator");
System.out.println("lookup successful");
System.out.println("Calling EJB method . . .");
int fibMax = 10;
int[] numbers =new int[fibMax];
for(int i = 1; i< fibMax; i++){
numbers[i] = i;
}
fibonacciCalculator.calculateFibonacci(numbers);
}

catch (Exception e) {
e.printStackTrace();
}
}
}



Output
## [CommonJWorkManager] executing in: default
Plan task FibonacciTask 1
Plan task FibonacciTask 2
Plan task FibonacciTask 3
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 1
Plan task FibonacciTask 4
## [FibWork] self-tuning workmanager: daveWM
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 2
Running task FibonacciTask 3
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 4
Plan task FibonacciTask 5
Plan task FibonacciTask 6
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 5
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 6
Plan task FibonacciTask 7
Plan task FibonacciTask 8
## [FibWork] self-tuning workmanager: daveWM
Plan task FibonacciTask 9
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 8
## [FibWork] self-tuning workmanager: daveWM
Running task FibonacciTask 9
Running task FibonacciTask 7
wm.waitForAll
workItem.result=4
workItem taskFibonacciTask 1 result=1
workItem.result=4
workItem taskFibonacciTask 2 result=1
workItem.result=4
workItem taskFibonacciTask 3 result=2
workItem.result=4
workItem taskFibonacciTask 4 result=3
workItem.result=4
workItem taskFibonacciTask 5 result=5
workItem.result=4
workItem taskFibonacciTask 6 result=8
workItem.result=4
workItem taskFibonacciTask 7 result=13
workItem.result=4
workItem taskFibonacciTask 8 result=21
workItem.result=4
workItem taskFibonacciTask 9 result=34
** Completed Fibonacci Computations in 17ms **
Fibonacci(1) = 1
Fibonacci(2) = 1
Fibonacci(3) = 2
Fibonacci(4) = 3
Fibonacci(5) = 5
Fibonacci(6) = 8
Fibonacci(7) = 13
Fibonacci(8) = 21
Fibonacci(9) = 34



WorkItems not finished on timeout - result 3
workItem.result=4
workItem taskFibonacciTask 41 result=165580141
workItem.result=4
workItem taskFibonacciTask 42 result=267914296
workItem.result=4
workItem taskFibonacciTask 43 result=433494437
workItem.result=3
workItem.result=3
workItem.result=3
workItem.result=3
workItem.result=3
workItem.result=3
** Completed Fibonacci Computations in 60115ms **
Fibonacci(1) = 1
Fibonacci(2) = 1
Fibonacci(3) = 2
Fibonacci(4) = 3
Fibonacci(5) = 5
Fibonacci(6) = 8
Fibonacci(7) = 13
Fibonacci(8) = 21
Fibonacci(9) = 34
Fibonacci(10) = 55
Fibonacci(11) = 89
Fibonacci(12) = 144
Fibonacci(13) = 233






Requests waiting for processing


All threads


Threads used
## [CommonJWorkManager] executing in: default
Plan task FibonacciTask 1
Plan task FibonacciTask 2
## [FibWork][ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 1
Plan task FibonacciTask 3
Plan task FibonacciTask 4
## [FibWork][ACTIVE] ExecuteThread: '15' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 3
## [FibWork][ACTIVE] ExecuteThread: '31' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 2
Plan task FibonacciTask 5
## [FibWork][ACTIVE] ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 4
## [FibWork][ACTIVE] ExecuteThread: '29' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 5
Plan task FibonacciTask 6
Plan task FibonacciTask 7
## [FibWork][ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 6
## [FibWork][ACTIVE] ExecuteThread: '30' for queue: 'weblogic.kernel.Default (self-tuning)' self-tuning workmanager: daveWM
Running task FibonacciTask 7
Plan task FibonacciTask 8
Plan task FibonacciTask 9