How to write Java services

I’m new to webMethods and need to find some examples or tutorials that explain how to write Java services in webMethods. I’ve created classes in Eclipse, but I need to come up to speed with this environment.

Can anybody help me out?



Hi Ted,

DeveloperUsersGuide.pdf has a lot of info which will definitely help you. Please do refer to that.


Be sure to read the various discussions on the forums about the use of Java services. When to create Java services and how Java code is structured is quite different from what you’re probably used to using Eclipse.

Java Services are written using the Developer tool. Here is a quick introduction:

1) Create the java service
(This presumes that you have created a package, and some folders)
Right click on the folder that you want to contain the java service.
Choose New à Java Service
Developer will create a new java service for you (it looks like a
coffee cup), highlighting its default name:
Type a new name for the service and hit enter

2) Code your service
The main window will show the empty service. A service is basically a static method that can is called by other flows.

Notice that the method signature (at the top of the pane) is
public static void (IData pipeline) throws ServiceException {

Your method call can get information set in the input/output tab by accessing the IData pipeline object. There are several ways to get information from the pipeline. (The pipeline is basically a wM proprietary hashmap). One way is to get an IDataCursor using the pipeline’s getCursor() method. Once you have a cursor, you can use it to traverse the pipeline, getting and setting values. There are several ways to use the cursor to get data. My preferred way is to use the IDataUtil static methods to access the cursor, but it is by no means the only way. At the end of your code, you should destroy your cursor (cursor.destroy()). If your code needs to throw an exception, use
throw new ServiceException(“”) or
throw new ServiceException(Exception).

Example code:

Here is an example that i created named ‘reverse’. It will reverse any String. I created it by making a new java service. Then on the input/output tab, i added a new String called ‘string’ for the input, and a new output called ‘result’. and then typed the following code:

IDataCursor cursor = pipeline.getCursor();

String input = IDataUtil.getString(cursor, “string”);

if (input != null) { //This is enforced in this example by ‘string’ being
//a required field, but is included for general
//good coding.
StringBuffer buffer = new StringBuffer();
cursor.insertAfter(“result”, buffer.toString());

Oddities and Notes:

The Integration Server must be able to see a java compiler. This means that the path on the Integration Server machine should have a java compiler visible. To test this, go to the command prompt of the IS machine, and type:

When you hit enter, you should see the javac usage. If you can’t see this, javac (the java compiler) is not in your path.

method conflicts
Keep in mind that each service is a static method for the same class. Classes are defined for each folder that contains a java service, not for each Java Service.

more than one method
You can make more than one method in a service. Just end the method ‘}’, and then start a new one (e.g. ‘public static void someOtherMethod {‘). At the end of the last method, don’t put the ending parenthesis in ‘}’, as wM Developer automatically does this for you. This allows you to create extra variables, methods, static initializers (ummm, i personally never use static initializers – they can be dangerous and are not OO) if you need them.

On the shared tab (below the main method pane), you can extend specific classes, and import classes if you need to.

wM introspection
You can invoke various wM introspective classes from within your code (e.g. Session object). Please see wM java API for details.

optional inputs
To make inputs optional, select the input in the input/output tab, then change the properties (upper right) to Required: False.

testing your code
Save often (each save forces a recompile). To test press the run button (looks like a green play button). A modal dialog will popup allowing you to type input values. Pressing ‘Ok’ will run the service. Results will show up in the ‘results’ pane (to the right).

Complex data structures
If you are dealing with documents, you must create new IData for the structure. Here is an example that creates a document (for output) named ‘context’ that contains four string fields (currency, encoding, language, timeZone).

IDataCursor cursor = pipeline.getCursor();
Session session = Service.getSession();

IData context = IDataFactory.create();
IDataCursor contextCursor = context.getCursor();

cursor.insertAfter(“context”, context);

Nice Quick introduction for the community!! Hope Ted and many others like him will benefit!

Great summary Greg. I’m sure it will be helpful to many.

Thought I’d throw my two-bits in on one point:

I think one should probably avoid this as a maintenance concern. “Where the heck is that ‘foobar’ method? Oh, here it is nested in ‘calcTheWorld’.”
[FONT=Times New Roman][SIZE=3]

[/size][/font]Can you elaborate on “dangerous?”

As far as “not OO,” the entire environment is more or less not OO–it’s service and procedurally oriented. Certainly the libraries under the covers are OO but the IS development environment is not. While the static methods that one writes are, strictly speaking, methods within an OO class, it is hard to say that these methods are true to the OO philosophy. They happen to be Java methods and use Java syntax, but Java services within IS are not the building blocks of an OO solution. The IS programming environment is very much procedurally-oriented rather than OO.

Re: Can you elaborate on “dangerous?”
Sure. a static initializer has no method signature and is not executed using the normal object --> message paradigm. As the class is loaded, the static initializer executes. If the code therein throws an exception, the class will fail to load. You will see a “Class not found” exception, not the exception you are looking for. This can be difficult to troubleshoot, as you will be puzzling over your classpath, not the code.
It is additionally dangerous in the context of a wM java service, suppose, for example i created a static initializer that throws an exception within a wM java service. When it throws exception, all of the other services associated with that class will “Class not found”. With a couple of lines of non-malicious, but errant code you could cripple an IS.

Re:As far as “not OO,”
Total agreement here (i am a former Smalltalker). Flow and the access it grants to java are not at all OO. Never have been, probably never will be.

Re: I think one should probably avoid this as a maintenance concern. "Where the heck is that ‘foobar’ method?
I agree. I note it as an oddity, not something you should do, except, perhaps to set a static variable. Also, the additional methods created are not accessible via flow, only via the other services in the same folder.

Additional general note: IMO, you should try to code in flow as much as possible, only write a java service when you have a direct need to (usually as utilities or as a known performance bottleneck).

That’s what I figured you were getting at but wanted to make sure. A good rule of thumb if one must use static initializers is to make them do as little as possible.

I’d offer that this should never be done. Static vars and helper methods are better defined in the Source pane of the Shared tab.

We are in violent agreement! :slight_smile:

If you want some viewable sample code, check out the WmSamples package in Developer. All of the java services can be viewed in the sample and tutorial folders.