Java programming in Webmethods

In the ITtoolbox forum, webmethods-l, Daniel Rivera posted the following:

[start]
Hello everyone,

I have been trying to find documentation on create and code Java services within webmethods and I have not had any luck with it. I tried looking in the archives and did not find anything that would have helped me so I now turn to you for help. The reason for this information request is that I am trying to create a service that will take in bytes and output those bytes to a stream. Any help that will point me in the right direction will be appreciated.
[end]

I tried to post the following but was denied by the moderator at ITtoolbox because I made reference to a “competitor” site. Here is the response that was denied:

[response]
Chapter 11: Building Coded Services, in the B2B Integrator Guide, describes how to build Java services (as well as other languages). That gives the basics of how to interact with the Integrator pipeline.

On the www.wmusers.com site is a Shareware section. I’ve uploaded a ZipFiles package that has an example of what you’re trying to do (byte array as input, writes them to a file using stream objects). It should get approved and made available within the next day or so.

Rob
[/response]

I’ve posted this here in hopes that Dan Rivera can find this answer.

Rob

Hi Rob,

I happened to be at a WebMethods training course and the instructor had told me about this website. I was suprised to find this post and I thank you for the help you have tried to provide. I will look over the zipfiles package and see what I can learn from it. Once again thanks for your help. =)

Rob,

I tried looking at your code and adapting it to write the incoming bytes to an outputstream with no luck. What follows is the code I am currently working with :

byte bytes;

// pipeline
IDataHashCursor pipelineCursor = pipeline.getHashCursor();
if ( pipelineCursor.first( “bytes” ) )
{
bytes = (byte) pipelineCursor.getValue();
}
else
{
throw new ServiceException(“Input Parameter ==> bytes not specified”);
}
pipelineCursor.destroy();

OutputStream os = null;
try {
os.write(bytes, 0, bytes.length);
os.flush();
}
catch (IOException ioe)
{
throw new ServiceException("IOException: " + ioe.getMessage());
}
finally // Always close an open stream
{
if(os != null)
{
try
{
os.close();
}
catch (IOException ignored)
{
}
}
}

I believe my problem is in the area where I try to write the bytes to an output stream. I am going to see if I can find more on the subject. Hopefully you could point me in the right direction.

Undoubtedly you’re getting a null pointer exception at the os.write() call.

You need to either pass an open OutputStream-derived object to the service or you need to create one within the service.

To where are you trying to write the bytes?

I am trying to write the bytes to a stream in the pipeline

Let me clarify myself a bit further. I am trying to take an object in the pipeline called bytes and converting it to an object in the pipeline called stream. I will then use this stream to create a mime object out of it.

Dan, how are you getting the bytes object in your pipeline to initially populate? Are you using a Built-In Service to retrieve data from a file; are you converting a String to the bytes object?

I am asking this because it may be simpler to get your stream than using the code posted above.

A Java service was created that coverts a stream to bytes prior to my having started work in the webmethods environment. Unfortunetly converting those bytes back to a stream does not exist.

We currently have a service in place that will receive an HTTP request that contains two headers and a stream. For debugging purposes the stream to bytes was created in the past to convert the stream to bytes and saving the pipeline to a file so that the developers would be able to debug this service. I cannot figure for the life of me how the previous developer used that service.

So hear I am trying to create the code to convert the bytes back to a stream so that I can pass that stream on to create mimeobjects from it. What follows is the code that converts the stream to bytes:

InputStream in = null;
String errorMessage = “”;

// pipeline
IDataHashCursor pipelineCursor = pipeline.getHashCursor();
if ( pipelineCursor.first( “content” ) )
{
Object o = pipelineCursor.getValue();
if (o == null || !(o instanceof InputStream))
{
IDataHashCursor pipelineCursor_1 = pipeline.getHashCursor();
pipelineCursor_1.last();
pipelineCursor_1.insertAfter( “errorMessage”, “No input stream”);
pipelineCursor_1.destroy();
return;
} // End if
in = (InputStream)pipelineCursor.getValue();
}
pipelineCursor.destroy();

int i = 0;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
while ((i = in.read()) >= 0) {
out.write(i);
} // End while
} // End try

catch (IOException ioerr) {
IDataHashCursor pipelineCursor_1 = pipeline.getHashCursor();
pipelineCursor_1.last();
pipelineCursor_1.insertAfter( “errorMessage”, ioerr.toString());
pipelineCursor_1.destroy();
return;
} // End catch

// pipeline
IDataHashCursor pipelineCursor_1 = pipeline.getHashCursor();
pipelineCursor_1.last();
pipelineCursor_1.insertAfter( “bytes”, out.toByteArray());
pipelineCursor_1.destroy();

The reason I am trying to convert the bytes back to a stream is so that the other developers can use the data when they save the pipeline to a file.

Dan, I’ve tried a 2 step flow for the purpose. Let us know if you are asking something different. After we get bytes in the input pipeline try using bytesToString & get a String & try using the following code. Here I’ve wrote the code so that it writes to a target directory, but it could be modified to suit other purposes.

try {IDataHashCursor pipelineCursor = pipeline.getHashCursor();
pipelineCursor.first( “TargetDir” );
String TargetDir = (String) pipelineCursor.getValue();
pipelineCursor.first( “dataString” );
String dataString = (String) pipelineCursor.getValue();
byte buf = dataString.getBytes();
OutputStream fout = new FileOutputStream(TargetDir);
for (int i=0; i < buf.length; i++)
{ fout.write(buf[i]);}
fout.close();
pipelineCursor.destroy();
} catch (Exception e)
{ IDataHashCursor pipelineCursor = pipeline.getHashCursor();
pipelineCursor.last();
pipelineCursor.insertAfter( “FileEx”, e.toString());
pipelineCursor.destroy();
}

Unfortunetly we do not need the bytes written to a file. We need it as a steam within the pipeline.
I will try and look elsewhere on how to create this stream

thanks for trying to help Rob.

Base on the service code you posted, I draw the following conclusions:

  1. The original input stream, the one that was converted to bytes, is what you would’ve passed to the http service you mention.

  2. You no longer have access to that stream and thus need to recreate it.

So, in your service where you tried to this:

OutputStream os = null;
try {
os.write(bytes, 0, bytes.length);
os.flush();
}

Do this instead:

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

IDataHashCursor pipelineCursor_1 = pipeline.getHashCursor();
pipelineCursor_1.last();
pipelineCursor_1.insertAfter(“stream”, bais);
pipelineCursor_1.destroy();

This is the reverse of the service you posted that converts the InputStream to bytes.

Let us know if this is what you need.

Dan, I think I got you covered.

Go to your pub.client:http service. In the Service In inputs, set the loadAs variable to “stream”. After the HTTP request is made, your response will be a stream object.

Next, call your custom streamToBytes service that the developer left for you. Do NOT drop the stream object from your pipeline. After this step, you will have both the bytes object and the stream object in the pipeline.

Next, when you call your savePipelineToFile, you will your stream in the file for other developers to use.

In short, leave the stream object in your pipeline and you should be okay to go.