Category: Java

Scripting Languages and COBOL

By spgennard, January 19, 2010 11:39 am

The use of scripting languages with other languages has increased over the last couple of years, from a simple case of interoperability, reuse of scripting code to allowing your code to customised via the user of external scripts. All of which are real world examples I have seen customers use.

Interoperability between languages is very important to COBOL environments just as much as other languages. Some platforms such as Microsoft’s .Net with their CLR makes life much easier by allowing all languages to share a common infrastructure ie: the instruction set and the VM (MSIL and CLR) along with a base class library to get you started.

Environments such as Sun’s VM (JVM) provide two different approaches to interoperability with Java, the first is via JNI/JNA and the second is producing bytecode that runs as is on the VM.

Although the Micro Focus COBOL compiler does not support JVM bytecode or Java source generation it does have support for invoking classes/methods via the OO invoke verb.

Using sun.jvmstat.monitor to see active Java processes

By spgennard, December 5, 2009 11:56 am

Monitor’ing Java processes can be achieved using the jvmstat monitor classes provided in the JVM. The documentation is a bit sketchy but with a little experimenting it can be done.

Below is a little example that shows you how to get a list of active Java processes.. which of course can then be used for other things :-)

Here’s the code…

import java.net.URISyntaxException;
import java.util.Set;

import sun.jvmstat.monitor.*;

public class sjps
{
   public static void main(String[] args)
          throws MonitorException, URISyntaxException
   {
      MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost("localhost");
      Set<Integer> activeVms = monitoredHost.activeVms();
      for (int psId : activeVms)
      {
         MonitoredVm monitoredVm = monitoredHost.getMonitoredVm
                   (new VmIdentifier(String.valueOf(psId)));
         String mainClass = MonitoredVmUtil.mainClass(monitoredVm, false);
         String vmVersion = MonitoredVmUtil.vmVersion(monitoredVm);
         String commandLine = MonitoredVmUtil.commandLine(monitoredVm);
         System.out.println(mainClass + " [" + psId + "]" +
                                       " using : "+vmVersion);
     System.out.println(" -> "+commandLine);
      }
   }

}

And to see the code running..

$ java sjps
sjps [865] using : 14.1-b02-90
 -> sjps
JConsole [863] using : 14.1-b02-90
 -> sun.tools.jconsole.JConsole

Java process id via java.lang.management

By spgennard, December 5, 2009 12:53 am

While working on a project recently I need to find out the current process of the active running Java process (for tracing/auditing), however I never found a 100% perfect solution but did come across an acceptable solution to use the management classes to query its name, which happens to have encoding in it, so here is the quick solution:

import java.lang.management.ManagementFactory;

public class getpid
{
  public static void main(String args[]) throws Exception
  {
      System.out.println("Process id : "+getProcessId());
  }

  public static long getProcessId()
  {
    String name = ManagementFactory.getRuntimeMXBean().getName();
    String[] nameBits = name.split("@");
   
    return nameBits == null ? -1 :  Long.valueOf(nameBits[0]);
  }
}
$ java getpid
Process id : 377

Fiddling with the JVM

By spgennard, November 9, 2009 9:10 pm

Java is a very safe language if used in a normal way, however just like the CLR it can be used in an unsafe manor.

The main reason for using Java in a unsafe manor is performance, some unsafe operations are optimised by the JVM itself.

The boot class loader grants enough permissions to access a key undocumented class sun.misc.Unsafe. As I will state, this is an undocumented class and as the name implies it’s unsafe.

This class provides methods that allows you to manipulate objects and the memory of the objects directly.

For example, you could use it to access the object itself, lets look at an example to manipulate a String object.. not nice I hear you say…. and boy are you are so right. The purpose of this example is to demonstrate the power of the JVM if used to the extreme but not to demonstrate how to destroy the JVM.

import sun.misc.Unsafe;
import java.lang.reflect.Field;

//  To Compile: javac BadBoy.java
//  To Run:        java -Xbootclasspath/p:. BadBoy

public class BadBoy
{
  private final static  Unsafe  unsafe  = Unsafe.getUnsafe();
 
  public static void main(String args[]) throws Exception
  {
   // Find the field "count" inside java.lang.String
   Field field = String.class.getDeclaredField("count");

   // Find the memory offset within the field...
   long countOffset = unsafe.objectFieldOffset(field);

   field = String.class.getDeclaredField("offset");
   long offset4Offset  = unsafe.objectFieldOffset(field);

   // Lets read the memory directory...
   Object  object = "Hello World from Java, the ultra safe language... or is it..";

   int length = unsafe.getInt(object, countOffset);
   System.out.println("The original Length is length: " + length);

   System.out.println("1- The 'object' contains : ");
   System.out.println(" -> "+object);
   System.out.println("  hashCode is : " + object.hashCode());

   unsafe.putInt(object, offset4Offset, 17);
   unsafe.putInt(object, countOffset, 32);
   System.out.println("2- The 'object' contains : ");
   System.out.println(" -> "+object);
   System.out.println("  hashCode is : " + object.hashCode());
 }
}

Then, the output of the example on my little macbook is:

stephen-gennards-macbook:blob spg$ java -Xbootclasspath/p:. BadBoy
The original Length is length: 60
1- The 'object' contains :
 -> Hello World from Java, the ultra safe language... or is it..
  hashCode is : 573430574
2- The 'object' contains :
 -> Java, the ultra safe language...
  hashCode is : 573430574

As you can see the String object is changed but the hashCode remains the same. :-)

Object COBOL/Java default exception handler

By spgennard, November 3, 2009 11:16 pm

While working on some support recently for our compiler (Micro Focus COBOL compiler that is), I became annoyed with the lack of a reasonable error messages/stack trace output from our Java/COBOL Object support.

I have no idea why our default exception handler for Java exceptions just displays a such a simple message with little or no information.

For those who have not seen it, display something similar to:

Exception 65537 not trapped by the class javaexceptionmanager.
Description: "Java exception"
Test error
Hit T to terminate program. Hit any other key to continue.
instantiated - test

Exception 65537 not trapped by the class javaexceptionmanager.
Description: "Java exception"
Test error
Hit T to terminate program. Hit any other key to continue.

Luckily for me and you, we do expose a mechanism for replacing the default exception handler.

Anyway, with very little effort I created a different “default” system exception handler that display this instead:

instantiated - test 1
java.lang.Exception: Test error
        at SimpleClass.TestException(SimpleClass.java:10)

WARNING: JavaException: Test error
instantiated - test 2
java.lang.Exception: Test error
        at SimpleClass.TestException(SimpleClass.java:10)
WARNING: JavaException: Test error

The key difference being that a Java stack trace is included, boy did this help me.

The program below is the code that implements the exception handler. I am sure someone else can take this example and make it much nicer and provide more features but for this blog I will keep it simple.

      $set ooctrl (+p-f) case
       program-id. ExceptionCatcher.
       
       class-control.
             EntryCallback is class          "entrycll"
             JavaExceptionManager is class   "javaexpt"
             ExceptionManager is class       "exptnmgr"
             Javasup is class "javasup"
             .
       
       working-storage section.
       01 wsCallback                   object reference.
       01 wsIterator                   object reference.
       01 theJavaException             object reference.
       local-storage section.
       01 filler pic x.   *> dummy storage item to allow recursion
       linkage section.
       01 lnkException                 object reference.
       01 lnkErrorObject               object reference.
       01 lnkErrorTextCollection       object reference.
       01 lnkErrorNumber               pic x(4) comp-5.
       01 anElement                    object reference.
         procedure division.
      *>---Set up system level Exception handler
             invoke EntryCallback "new" using
                    z"JException"
                    returning wsCallback
             end-invoke

             invoke ExceptionManager "register" using
                    javaexceptionmanager
                    wsCallback
             end-invoke

             invoke EntryCallback "new" using z"DispError"
               returning wsIterator
             end-invoke

             goback.
       
       
         entry "Jexception" using
                  lnkException
                  lnkErrorNumber
                  lnkErrorTextcollection
             .

              invoke javasup "exceptionOccurred"
                   returning theJavaException
              end-invoke

              if theJavaException not equal null
                invoke theJavaException "printStackTrace"
              end-if
           
              invoke lnkErrorTextCollection "do" using wsIterator
              goback.
             .

          entry "DispError" using anElement
            display "WARNING: JavaException: " with no advancing
            invoke anElement "display"
            display " "
            goback.
             .

To use the above code, you just have to first cut-paste to code into a file called ExceptionCatcher.cbl and include this in your project, and then add the directive INITCALL”ExceptionCatcher”, then away you go.

Panorama Theme by Themocracy - tweaked by SpG

AWSOM Powered