Like any good manager, it insulates you from unpleasant things. The goal is to help you migrate off of the com.ibm.websphere.asynchbeans.WorkManager
API. It provides a WorkExecutor
interface that's similar to IBM's WorkManager
, but uses the niceties of Executor
and friends like Future
. The API is purposely similar, so porting should be straightforward.
We provide implementations of WorkExecutor
that are backed by WorkManager
or by java.util.concurrent.ExecutorService
. This provides an easy path to removing the use of WorkManager
: first target WorkExecutor
's API and keep using the same WorkManager
under the hood. Then, switch to using the ExecutorService
-backed implementation when you're ready to completely sever any dependency on WorkManager
.
It's compatible with Java 6 because if you're using WorkManager
, you're probably using a pretty old system!
Artifacts are available in JCenter.
Gradle:
compile 'io.aexp.concurrency.middle-manager:middle-manager-core:1.0.1'
compile 'io.aexp.concurrency.middle-manager:middle-manager-ibm:1.0.1'
Maven:
<dependency>
<groupId>io.aexp.concurrency.middle-manager</groupId>
<artifactId>middle-manager-core</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>io.aexp.concurrency.middle-manager</groupId>
<artifactId>middle-manager-ibm</artifactId>
<version>1.0.1</version>
</dependency>
At a high level, these are the steps to use this library :
- Add dependencies on
io.aexp.concurrency.middle-manager:middle-manager-core
andio.aexp.concurrency.middle-manager:middle-manager-ibm
(see above). - Migrate implementations of
Work
to implement onlyRunnable
.Work
extendsRunnable
, so you can leaveWork
there for now if you want to use the sameWork
implementations in both oldWorkManager
code and newWorkExecutor
code. - Wrap
WorkManager
instances with aWorkManagerWorkExecutor
. Instead of castingWorkItem#getResult()
to the originalWork
submitted toWorkManager#doWork()
, you'll get aFuture<T>
whereT
is yourRunnable
implementation. - Remove any remaining
implements Work
-- simplify it to justimplements Runnable
. You can also remove the extra method implementations that Work requires that are now no longer needed. - Migrate usage of
WorkManagerWorkExecutor
to useExecutorWorkExecutor
instead. - Remove all code that created or otherwise accessed
WorkManager
instances since they're no longer used to power theWorkExecutor
s
When you no longer need the IBM implementation, remove the middle-manager-ibm
dependency, as well as whatever dependency you were using to access WorkManager
.
Integration will depend on how you're currently accessing your WorkManager
objects. We, for instance, use logic like the below snippet to determine which WorkExecutor
to use, but it's likely to be custom to your situation.
private static boolean shouldUseExecutorImpl() {
// allow forcing either way via system property
String type = System.getProperty("com.foo.bar.baz");
if ("workmanager".equals(type)) {
return false;
}
if ("executor".equals(type)) {
return true;
}
// true if you appear to be on a grown-up computer; will be false on legacy deployment. This is handy for running tests, etc.
String arch = System.getProperty("os.arch");
return System.getProperty("java.version").startsWith("1.8.")
&& (arch.equals("amd64") || arch.equals("x86_64"));
}
Once you've figured out how you wish to handle getting an WorkExecutor
instead of a WorkManager
(e.g. you could load a WorkManager
from JNDI or however you're doing that, but then wrap that in a WorkManagerWorkExecutor
), you'll want to migrate code from looking like this:
WorkItem item = workManager.startWork(new FooTask());
// could also assemble an ArrayList and call WorkManager#join()
while (item.getStatus() != WorkEvent.WORK_COMPLETED) {
Thread.sleep(1234);
}
// Only provides the ability to return the original Work as a means of expression completion
FooTask task = (FooTask) item.getResult();
// This usually means that the Work implementation writes to its own field, or something like that
String result = task.fieldThatWasWrittenToDuringExecution;
to this:
Future<FooTask> future = workExecutor.submit(new FooTask());
// no need to change the structure of FooTask and how it records its result
String result = future.get().fieldThatWasWrittenToDuringExecution;
Once you're that far, it's a small leap to making FooTask
implement Callable<String>
, and then you can get a Future<String>
directly.
WorkManager
, WorkItem
, and friends form an old concurrency API from the early days of Java. It was originally intended to provide concurrency tools to webapps running inside an app server like WebSphere. There are actually several flavors of it: CommonJ, IBM, and even an attempt at standardization in Java EE. All three are similar, and while this project includes an implementation that can use an IBM WorkManager
as the actual thread handling mechanism, it would be straightforward to also implement this on top of the CommonJ or Java EE 5 flavors. Since all three APIs are similar, this library is useful for migrating away from all three.
If you want to build everything except the IBM subproject, add the middleManager.excludeIbmSubproject
Gradle property to your build, as in:
./gradlew build -PmiddleManager.excludeIbmSubproject
Unfortunately, there isn't a publicly available source for the com.ibm.websphere.asynchbeans.*
classes, so this project's IBM subproject will not build without some manual setup. In your WebSphere installation, there is probably an asynchbeans.jar
file somewhere that has those classes in it. Drop that jar in the middle-manager-ibm/ext-jars
dir within this project and gradle will find the classes it needs to build middle-manager. If you have a runtime
jar, that may also contain the WorkManager
classes.
We welcome Your interest in the American Express Open Source Community on Github. Any Contributor to any Open Source Project managed by the American Express Open Source Community must accept and sign an Agreement indicating agreement to the terms below. Except for the rights granted in this Agreement to American Express and to recipients of software distributed by American Express, You reserve all right, title, and interest, if any, in and to Your Contributions. Please fill out the Agreement.
Any contributions made under this project will be governed by the Apache License 2.0.
This project adheres to the American Express Community Guidelines. By participating, you are expected to honor these guidelines.