Java通过JNI C代码调用HP Tandem上的Cobol程序

时间:2016-05-04 00:42:57

标签: java java-native-interface cobol hp-nonstop tandem

我想通过java jni C代码调用Cobol程序。     在调用我的java代码后,我收到以下错误:Java运行时环境检测到致命错误:pcs的SIGSEGV(0xb)= fffffffff2667174,pid = 1174405432,tid = 4

这是我在Tandem编译的Cobol程序(XCOBFUNC.cob):ecobol -c -Wshared XCOBFUNC.cob

    ?ENV COMMON;INNERLIST
    ?INSPECT, SYMBOLS

    IDENTIFICATION DIVISION.
    PROGRAM-ID.    XCOBFUNC.
    AUTHOR. TEST.

    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
        SOURCE-COMPUTER.        TANDEM-K2006.
        OBJECT-COMPUTER.        TANDEM-K2006.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 D-RESULT        PIC S9(09) COMP.

    LINKAGE SECTION.
    77 D-STRING        PIC X(20).
    77 D-SHORT         PIC 9(04) COMP.
    77 D-LARGE         PIC 9(08) COMP.

    PROCEDURE DIVISION USING D-STRING, D-SHORT, D-LARGE.
    000-INIT.
        DISPLAY "I AM DOING COBOL NOW".
        COMPUTE D-RESULT = D-LARGE / D-SHORT.
        DISPLAY "D-STRING = " D-STRING.
        DISPLAY "D-LARGE = " D-LARGE.
        DISPLAY "D-SHORT = " D-SHORT.
        DISPLAY "D-RESULT = " D-RESULT.
        DISPLAY "LEAVING COBOL PROGRAM NOW".
        EXIT-PROGRAM.

这是我的C源文件(HelloJNI.c):

#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
#include "cobincl.h"

// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT jshort JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj, jint par1, jstring jName) {

   char outCStr[128] = "From C Program";
   jshort error = 0;
   short ds;
   long dl;
   char *tx = "Displayed in COBOL";

   const char *name = (*env)->GetStringUTFChars(env, jName, 0);
   int i;
   jint result = par1 + 5;


   printf("Hello World!\n");
   printf("par1 = %d \n", par1);
   printf("par1 = %s \n", name);

   (*env)->ReleaseStringUTFChars(env, jName, name);

   ds = 100;
   dl = 40000;

   XCOBFUNC(tx, &ds, &dl);   

   printf("ds = %d\n", ds);

   printf("I am back in C now and program is ending.\n");   

   return error;
}

这是我的C头文件(HelloJNI.h):

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */

#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloJNI
 * Method:    sayHello
 * Signature: (ILjava/lang/String;)S
 */
JNIEXPORT jshort JNICALL Java_HelloJNI_sayHello
  (JNIEnv *, jobject, jint, jstring);

#ifdef __cplusplus
}
#endif
#endif

这是我的cobincl.h:

void XCOBFUNC (char *, short *, long *);
#pragma FUNCTION XCOBFUNC (cobol)

这是我的Makefile:

CC=/usr/bin/c89
ELD=/usr/bin/eld

RM=rm -f

CFLAGS= -g -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/oss -I /G/system/system -I./include -Wallow_cplusplus_comments \
        -Wextensions -D_XOPEN_SOURCE_EXTENDED=1 -Wnowarn=141,209,1506,262 \
        -Wcall_shared -Wsystype=oss -Wtarget=tns/e -Wmap -Wverbose

#LDFLAGS = -set floattype IEEE_float -set SYSTYPE OSS -set HIGHPIN ON \
#          -set CPlusPlusDialect neutral -dll -m -verbose \
#          -l zcobdll -lcre -lcrtl -export_all

LDFLAGS = -set floattype IEEE_float -set SYSTYPE OSS -set HIGHPIN ON \
          -set CPlusPlusDialect neutral -dll -m -verbose \
          -lcre -lcrtl -l zcobdll -export_all


ALL = libhello.so

.SUFFIXES: .java .class .h .c .o 

.c.o: 
    $(CC) $(CFLAGS) -c $<

all: $(ALL)

clean:
    @$(RM) *.o *.so

HelloJNI.o: cobincl.h HelloJNI.h HelloJNI.c

libhello.so: HelloJNI.o XCOBFUNC.o
      $(ELD) HelloJNI.o XCOBFUNC.o -o libhello.so $(LDFLAGS)

这是我的java代码:

public class HelloJNI {
   static {
      System.loadLibrary("hello"); // Load native library at runtime
                                   // hello.dll (Windows) or libhello.so (Unixes)
   }

   public HelloJNI() {

   }

   public void sendToC() {

       int par1 = 5;
       String name = "Test";


       short temp = sayHello(par1, name);
       System.out.println("temp = " + temp);
   }



   // Declare a native method sayHello() that receives nothing and returns void
   private native short sayHello(int par1, String name);
   //private native String sayHello(int par1, String name, String[] tokensKeys, String[] tokensValues);

   // Test Driver
   public static void main(String[] args) {
      //new HelloJNI().sayHello();  // invoke  the native method
      HelloJNI myObject = new HelloJNI();

      myObject.sendToC();

   }
}

我感谢任何帮助,如果有人能告诉我任何关于java通过JNI C程序如何在HP Tandem Non-Stop上调用Cobol程序的例子,那将会很棒。

Please see from compilation process:

File: /usr/local/home/urily/Java_C_COBOL/c/libcobol.so
    Segment(Read/Write/Execute)       Address             Size 
---------------------------------------------------------------------------
    text(Read/Execute)          0x0000000078000000     0x00002000


File: libhello.so
    Segment(Read/Write/Execute)
      Section                         Address             Size
---------------------------------------------------------------------------
    text(Read/Execute)          0x0000000078000000     0x00001000
      .tandem_info              0x0000000078000190     0x00000198
      .lic                      0x0000000078000328     0x00000188
      .dynamic                  0x00000000780004b0     0x00000150
      .liblist                  0x0000000078000600     0x00000020
      .dynstr2                  0x0000000078000620     0x00000032
      .IA_64.unwind             0x0000000078000658     0x00000048
      .IA_64.unwind_info        0x00000000780006a0     0x00000018
      .IA_64.unwind.strings     0x00000000780006b8     0x0000004a
      .rconst                   0x0000000078000710     0x00000030
      .plt                      0x0000000078000740     0x00000020
      .text                     0x0000000078000780     0x00000080
      .hash                     0x0000000078000800     0x000000dc
      .dynsym                   0x00000000780008e0     0x00000360
      .dynstr                   0x0000000078000c40     0x000001bd
      .hashval                  0x0000000078000e00     0x00000090
      .rela.dyn                 0x0000000078000e90     0x00000030

我看到libhello.so和libcobol.so的段具有相同的地址     0x0000000078000000。我通过两个步骤手动创建了libcobol.so:

  1. cobol -c -Wcall_shared -Wsystype = oss -Wmap XCOBFUNC.cob
  2. / usr / bin / eld XCOBFUNC.o -o libcobol.so -dll -m -verbose -l zcobdll -lcre -lcrtl
  3. 如何创建具有不同地址的文本段,因为它们现在都具有相同的地址?

    在我的hs_err_pid.log下面

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=fffffffff2667174, pid=620757215, tid=4
    #
    # JRE version: 6.0
    # Java VM: Java HotSpot(TM) Server VM (16.3-b01-svcnedccadmin:2011apr20-08:12 mixed mode nsk oss-ia64 )
    # Problematic frame:
    # C  [(DLL zcrtldll)+0x0]  printf + 0xF0 (DLL zcrtldll)+0x0
    #
    #  Please report this error to HP customer support.
    #
    
    ---------------  T H R E A D  ---------------
    
    Current thread (8330800):  JavaThread "main" [_thread_in_native, id=4, stack(809e000,81a1400)]
    
    
    Frame 0: __stdio_fp + 0x171 (DLL zcrtldll)
            pc    : 0xfffffffff2667171
            ra    : 0xfffffffff26d6bf0
            sp    : 0x081a0510
            psp   : 0x081a0540
            cfm   : 0x0000020c      sol(ins+locals)=4, sof(ins+locals+outs)=12, sor=0
            bsp   : 0x081a1a10
            fpsr  : 0x9804c8a74433f
            pr    : 0x00008cbd
            br[0] : 0xfffffffff26d6bf0
            br[1] : 0x640303a0
            br[2] : 0x00000000
            br[3] : 0x00000000
            br[4] : 0x00000000
            br[5] : 0x00000000
            br[6] : 0xfffffffff26d6b00
            br[7] : 0xfffffffff90babc0
            lc    : 0x00000000
            ec    : 0x00000000
    
            gr0   : 0x00000000      0
            gr1   : 0x6cec84b0      1827439792
            gr2   : 0x6cec8608      1827440136
            gr3   : 0x7de00010      2111832080
            gr4   : 0x6cec84b0      1827439792
            gr5   : 0x081a0908      135923976
            gr6   : 0x080a2000      134881280
            gr7   : 0x0829e800      136964096
            gr8   : 0x64011640      1677792832
            gr9   : 0x00000008      8
            gr10  : 0x08330800      137562112
            gr11  : 0x00000000      0
            gr12  : 0x081a0510      135922960
            gr13  : 0xe0000002300009b6      -2305842999818450506
            gr14  : 0x7de00010      2111832080
            gr15  : 0x7de00028      2111832104
            gr16  : 0xfffffffff26d6b00      -227710208
            gr17  : 0x00000000      0
            gr18  : 0x00000000      0
            gr19  : 0x00000000      0
            gr20  : 0x7dde01e0      2111701472
            gr21  : 0x081a0870      135923824
            gr22  : 0x081a0878      135923832
            gr23  : 0x081a2038      135929912
            gr24  : 0x7dde0100      2111701248
            gr25  : 0x7dde0100      2111701248
            gr26  : 0x8000000000000000      -9223372036854775808
            gr27  : 0x6cf24918      1827817752
            gr28  : 0x0000000c      12
            gr29  : 0x00000001      1
            gr30  : 0x00000000      0
            gr31  : 0x00000000      0
            gr32  : 0x00000001      1
            gr33  : 0xc00000000000050d      -4611686018427386611
            gr34  : 0xfffffffff26d6bf0      -227709968
            gr35  : 0x6cec84b0      1827439792
            gr36  : 0x081a0800      135923712
            gr37  : 0x8330fcc00000000       590833344963411968
            gr38  : 0x081a08b4      135923892
            gr39  : 0x0c6221a8      207757736
            gr40  : 0x64099e10      1678351888
            gr41  : 0x7eec9bb0      2129435568
            gr42  : 0x08325fa0      137519008
            gr43  : 0x08325fa0      137519008
            fr1   : (0x0ffff,0x8000000000000000)    1
    
    Stack: [809e000,81a1400],  sp=81a0540,  free space=%pk
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C  [(DLL zcrtldll)+0x0]  printf + 0xF0 (DLL zcrtldll)+0x0
    
    Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
    j  HelloJNI.sayHello()V+0
    j  HelloJNI.main([Ljava/lang/String;)V+7
    v  ~StubRoutines::call_stub
    
    ---------------  P R O C E S S  ---------------
    
    Java Threads: ( => current thread )
      106de800 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=12, stack(10a69000,10aa8800)]
      106da200 JavaThread "CompilerThread1" daemon [_thread_blocked, id=10, stack(10965000,109e4800)]
      1059b600 JavaThread "CompilerThread0" daemon [_thread_blocked, id=9, stack(10861800,108e1000)]
      106d4800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=8, stack(107e0000,1081f800)]
      106b4000 JavaThread "Finalizer" daemon [_thread_blocked, id=7, stack(1075e000,1079d800)]
      1062c400 JavaThread "Reference Handler" daemon [_thread_blocked, id=6, stack(1062f800,1066f000)]
    =>8330800 JavaThread "main" [_thread_in_native, id=4, stack(809e000,81a1400)]
    
    Other Threads:
      105a6800 VMThread [stack: 105a9000,105e8800] [id=5]
      106c2e00 WatcherThread [stack: 803c800,804c000] [id=11]
    
    VM state: not at safepoint (normal execution)
    
    VM Mutex/Monitor currently owned by a thread: None
    
    Heap
     def new generation   total 3712K, used 228K [8450000, 8850000, 99a0000)
      eden space 3328K,   6% used [8450000, 8489150, 8790000)
      from space 384K,   0% used [8790000, 8790000, 87f0000)
      to   space 384K,   0% used [87f0000, 87f0000, 8850000)
     tenured generation   total 8192K, used 0K [99a0000, a1a0000, c450000)
       the space 8192K,   0% used [99a0000, 99a0000, 99a0100, a1a0000)
     compacting perm gen  total 65536K, used 1865K [c450000, 10450000, 10450000)
       the space 65536K,   2% used [c450000, c6225a0, c622600, 10450000)
    No shared spaces configured.
    
    
    VM Arguments:
    java_command: HelloJNI
    Launcher Type: SUN_STANDARD
    
    Environment Variables:
    JAVA_HOME=/usr/tandem/java
    PATH=/bin:/bin/unsupported:/usr/bin:/usr/ucb:/usr/tandem/java/bin:/usr/tandem/javaexth10/bin:/usr/tandem/sqlmx/bin:/usr/tandem/java/jre/bin:/usr/tandem/jdbcMx/current/bin:/usr/oracle/ggs:/usr/tandem/nssoap/t0865h01_AAX/tools:.:
    SHELL=/bin/sh
    
    
    ---------------  S Y S T E M  ---------------
    
    OS:uname:NONSTOP_KERNEL dnb1 J06 19 NSE-W
    
    CPU:total 1
    
    Memory: 4k page, physical 0k
    
    vm_info: Java HotSpot(TM) Server VM (16.3-b01-svcnedccadmin:2011apr20-08:12) for nsk oss-ia64 JRE (1.6.0), built on Apr 20 2011 09:18:56 by "svcnedccadmin" with c89
    
    time: Mon May  9 18:51:12 2016
    elapsed time: 1 seconds
    

1 个答案:

答案 0 :(得分:0)

我不知道什么是串联:ecobol,我的gnucobol示例有效:

CallingCOBOL.java:

class CallingCOBOL {
    private native void adaptor(String from_java);
    public static void main(String[] args) {
        new CallingCOBOL().adaptor("Hello world!");
    }
    static {
        System.loadLibrary("adaptor");
    }
}

adaptor.c:

#include "dlfcn.h"
#include "jni.h"
#include "libcob.h"
#include "adaptor.h"
#include "stdio.h"
JNIEXPORT void JNICALL Java_CallingCOBOL_adaptor(JNIEnv * env, jobject obj, jstring string_from_java) {
    cob_init(0, NULL);
    void * sub_cob;
    sub_cob = dlopen("./libsub-cob.so", RTLD_NOW);
    if (!sub_cob) {
        puts("error no lib found");
        return;
    }
    puts("lib loaded");
    void(*proc_cob)(char*) = (void(*)(char*))dlsym(sub_cob, "proc__cob");
    if (proc_cob) {
        printf("proc addr is %p\n", proc_cob);
    } else {
        puts("proc addr is null");
    }
    const char *temp = (*env)->GetStringUTFChars(env, string_from_java, 0);
    puts("took string from java environment");
    proc_cob(temp);
    puts("cobol proc run ok");
    (*env)->ReleaseStringUTFChars(env, string_from_java, 0);
    dlclose(sub_cob);
    return;
}

子cob.cbl:

identification division.
program-id. sub-cob.
environment division.
configuration section.
data division.
working-storage section.
01 temp-string pic x(20) based.
01 pchar usage pointer.
01 my-string pic x(20).
linkage section.
01 string-from-java pic x(20).
procedure division.
sub-cob section.
goback.
entry "proc-cob" using by reference string-from-java.
display "entry proc-cob".
set pchar to address of string-from-java.
display "pchar set".
set address of temp-string to pchar.
display "temp-string set"
string temp-string delimited by x"00" into my-string.
display "my-string set".
display my-string.
goback.

生成文件:

default:
        javac CallingCOBOL.java;
        javah CallingCOBOL;
        mv CallingCOBOL.h adaptor.h;
        gcc -shared -fPIC adaptor.c -I/usr/java/jdk1.8.0_92/include/linux -I/usr/java/jdk1.8.0_92/include -lcob -olibadaptor.so;
        cobc sub-cob.cbl -free -olibsub-cob.so;
clean:
        rm CallingCOBOL.class;
        rm adaptor.h;
        rm libadaptor.so;
        rm libsub-cob.so;