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.
COBOL, JVM, Java, Scripting, Tips
|
COBOL, javascript, javax.script, JSR 223, Micro Focus, Net Express, ScriptEngine, ScriptEngineManager, Scripting, ScriptObject
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
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
Having read a recent bog about COBOL and type-safety, I though I would jot down some comments.
ANS85 COBOL is naturally is type-unsafe due as every data item being part of one memory region (or storage area), because of this it can make is difficult to talk to type-safe language such as Java or the CLR.
However, just like any computer language it does not stay still. Object oriented features were added to COBOL, at this point in time you we were given the verbs to create 100% type safe application.
The key to writing type safe code is the use OBJECT-REFERENCE will a TYPE and using them on in your methods and using the INVOKE verb.
For example:
IDENTIFICATION DIVISION.
PROGRAM-ID. "TypeSafeExample".
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS SYS-STRING AS "System.String".
DATA DIVISION.
WORKING-STORAGE SECTION.
01 hello-world-string OBJECT REFERENCE SYS-STRING.
PROCEDURE DIVISION.
SET hello-world-string TO "Hello World"
DISPLAY hello-world-string
STOP RUN.
The use of COBOL pictures can still be used, however for easy interop with other type-safe languages you really have to stick to the right types for your target environment when exposing your COBOL program to the other languages, this means if you are creating classes, the method to be consumed by other languages should use standard types, for .Net/CLR applications the use of CLS-COMPLIANT types is the right approach. For JVM applications, keep to the “core” java.lang types.
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.