Click here to Skip to main content
15,883,990 members
Articles / .NET

Using jtOpen from .NET Code - IKVM

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
5 Mar 2012CPOL4 min read 22.9K   5   7
Using jtOpen from .NET Code - IKVM

A development we were working on required us to submit an AS400 job and wait for that job to complete. It was quite a long process that involved numerous file operations and sockets communication to various sub systems.

We had to submit the job using the SBMJOB command which looked similar to this...

SBMJOB CMD(CALL PGM(ORD040CL) PARM('0000157')) JOB(CREATE_ORDS) JOBQ(*JOBD)

This is simple enough using either the COM interop library cwbx.dll (IBM AS/400 iSeries Access for Windows ActiveX Object Library) or the managed .NET provider IBM.Data.DB2.iSeries. However, because you are submitting the job rather than running it interactively, responsibility for processing that job is passed to the AS400. Using either the COM or .NET tools, there was no simple way to search for jobs by name or system.

After a bit of searching and speaking with smug Java colleagues, I learned that this is very simple to do in Java using the open source toolkit jtOpen.

jtOpen exposes a number of classes that aren't available in either of the COM or .NET libraries. The main class I was interested in was JobList. IBM even has a nice example of exactly what I was trying to achieve:

Since the code is open source, I thought I'd have a quick look and see if it would be a simple case to port the code I was interested in into a .NET library. Unfortunately, this wasn't the case - the JobList class actually performs a number of API calls in order to retrieve a handle to a list of objects and iterate them. You can view the source here if you like.

What I wanted to do was simply use the Java code from within my .NET code. This is where IKVM comes to the rescue.

IKVM ships with a Bytecode compiler named ikvmc. Using this tool, you can run the jar file through ikvmc and create a DLL file that you can reference from your .NET code.

Have a look at the command line options available for ikvmc. The JobList class exists in the main jt400.jar file, so to convert it to a DLL, you would use syntax similar to:

ikvmc -target:jt400.jar -out:jt400.dll

You might see a few warnings while creating the DLL, but you should still find that jt400.dll has been created OK.

Once the DLL is ready, go to Visual Studio and reference the file in your project. You might think that's all that's required, but you still need to add all the references to provide the bridging between your .NET code in the Java source. If you look in the bin directory of your IKVM download, you'll find numerous libraries prefixed IKVM.OpenJDK - you'll need to include some of these so that your jt400 library will work OK.

I couldn't find any obvious reference for which files were required, so a bit of trial and error was needed here. Eventually, the minimum references that I needed for jt400 to work were...

IKVM.OpenJDK.Beans.dll
IKVM.OpenJDK.Core.dll
IKVM.OpenJDK.SwingAWT.dll
IKVM.OpenJDK.Text.dll
IKVM.OpenJDK.Util.dll
IKVM.OpenJDK.Runtime.dll

Once these references are included, you should be able to use the library OK. Taking the IBM example link from earlier in this article, you could use library to find jobs that match a name by writing a .NET method similar to:

C#
[Serializable]
public class JobDetails
{
    public string Status { get; set; }
    public string Number { get; set; }
    public string Name { get; set; }
}

/// <summary>
/// Gets a list of jobs from the target server that match the specifed JOB_NAME
/// </summary>
/// <param name="system">
/// The name of the AS400 target server to retrieve the job list from</param>
/// <param name="user">
/// The security user to authenticate with the target server</param>
/// <param name="password">
/// The security password to authenticate with the target server</param>
/// <param name="jobName">
/// The name of the job to limit results by </param>
/// <returns>A list of jobs that match the specifed criteria</returns>
public List<JobDetails> GetJobsByName(string system, string user, string password, string jobName)
{
    List<JobDetails> results = new List<JobDetails>();
    AS400 server = new AS400();

    server.setSystemName(system);
    server.setUserId(user);
    server.setPassword(password);

    JobList list = new JobList(server);
    list.addJobSelectionCriteria(JobList.SELECTION_JOB_NAME, jobName);

    try
    {
        Enumeration items = list.getJobs();
        while (items.hasMoreElements())
        {
            Job job = (Job)items.nextElement();
            var details = new JobDetails
            {
                Name = job.getName().Trim(),
                Number = job.getNumber().Trim(),
                Status = job.getStatus().Trim()
            };
            results.Add(details);
        }

        if (server.isConnected())
        {
            server.disconnectAllServices();
        }
    }
    catch (Exception ex)
    {
        throw new ApplicationException(
            string.Format("Failed to retrieve jobs from server {0}", system), ex);
    }

    return results;
}

There are a number of attributes you can use to filter and search the jobs on the server, however, for this example I only needed to find jobs that matched a specified JOB_NAME. I created a simple class to hold the Job Details I was interested in (Status, Number and Name) and had my method return that rather than anything from the jt400 DLL.

This works really well and we can now find all jobs that match a specifed job name from our .NET code - happy days.

The only downside to using jtOpen in .NET is that I don't particularly like mixing the Java cased language with .NET, but there's no way around this if you want to consume the library without porting it by hand. Instead, think about keeping code that uses jtOpen separate from your main application code and write a wrapper method similar to GetJobsByName that hides the jtOpen syntax and returns .NET objects you have created. This will keep your source clean and consistent.

Hope that helps anyone else who wants to use jtOpen in .NET!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCan not convert jt400.jar file Pin
DevlynZioN6-Jan-14 20:30
DevlynZioN6-Jan-14 20:30 
AnswerRe: Can not convert jt400.jar file Pin
DevlynZioN7-Jan-14 0:47
DevlynZioN7-Jan-14 0:47 
GeneralMy vote of 5 Pin
SunKwon5-Feb-13 22:53
SunKwon5-Feb-13 22:53 
BugPermission denied: connect error Pin
ericnewton7615-Mar-12 11:50
ericnewton7615-Mar-12 11:50 
GeneralRe: Permission denied: connect error Pin
Dylan Morley16-Mar-12 3:29
Dylan Morley16-Mar-12 3:29 
AnswerRe: Permission denied: connect error Pin
ericnewton7620-Mar-12 5:28
ericnewton7620-Mar-12 5:28 
GeneralRe: Permission denied: connect error Pin
Dylan Morley20-Mar-12 6:53
Dylan Morley20-Mar-12 6:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.