GnuCOBOL can easily link to anything C, and JNI is available. If you are doing a large integration, the SWIG tool would likely be very smart place to start. COBOL to C, then SWIG the C to and from Java.
There is a grand contribution to GnuCOBOL by László Erdős, COBJAPI, direct access to AWT features from COBOL user defined functions. Very well documented, loads of examples.
Yeah, it does make it pretty easy. I'll put a sample in the FAQ. A couple of issues.
You can't SWIG from COBOL, you'll need to go through the generated C.
use -g to have the generated C files hang around, or use -save-temps
The prototypes are in the program.c files, not the the .c.h or c.l.h, so that's a pain, meaning there is no lazy mode and simply including the header in the SWIG interface file, the entry points will need to be listed explicitly in the .i file.
.i files are overwritten by the preprocessor, so there needs to be an extra name, program-swig.i and not a SWIG program.i, as GnuCOBOL will use program.i as part of its internal text preprocessor.
And the big one:
GnuCOBOL mangles variable names beyond recognition. There is no way around that one at this time. 01 important-data pic x(80) external. Won't cut it, the .c.h file (or .c.l.h or .c.l1.h .c.l2.h...) will have a generated name akin to b_5, or b_17, and the generated name will change on each compile, and there is no consistent ryhme or reason to the naming (well there is, but it changes with each new entry in working-store, and a host of other factors due to the abstract symbolic tree used by the compiler). So to get at data, you need to write a program and return it (plus it's length) or write a C function that squirrels into linkage section by going through cob_global to cob_module and the shadow CALL parameter cob_field array, and even this won't be by COBOL name in C, it'll be by position in CALL arguments.
Cheers,
Brian
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
procedure division using some-item.
a-main section.
display 'foo'
goback.
we already have JAVA classes to map some-item to subordinate data items in JAVA, and to supply the whole thing as a byte array.
So in JAVA we need to call 'COBOL' passing a reference (pointer) to our byte array.
Then, if the COBOL program changes storage within the some-item , we see it back in JAVA when the call is finished.
So, I don't need to access working-storage items directly, just pass the reference pointer of our byte array to the called program. SWIG seems overkill for this at first glance.
Works quite well with Micro Focus, but they have helper classes in a jar to make this easy (new ParameterList, and then adding POINTER values to the call parameter list).
I don't know JAVA half as well as COBOL though, an example or two, or some documentation on the topic would be super.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Was Gary Cowell's post deleted on purpose? By mistake? Or is this a SourceForge glitch? The summary screen still shows a link (though it won't once I make this post) and I got an email copy, so can reproduce his entry, but I'm not seeing it here. Don't want to just add it back in if it was deleted on purpose.
Curious,
Brian
Last edit: Brian Tiffin 2016-01-15
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Repost from copy/paste of what I can see from original post by Gary Cowel.
Odd. I've noticed something possibly simimlar (appear on summary page, not in list of posts within acrual area) with some anonymous posts over the last few months. Sorts itself out after some time with those, so didn't think much of it. Could be a different issue.
I'm very interested also in being able to call Gnu COBOL modules from Java with JNI
Our current application uses Micro Focus with its runtime system jar.
I suspect though, that's overkill for what we need.
We need to instantiate a COBOL runtime, then invoke a module passing LINKAGE items as byte arrays.
procedure division using some-item.
a-main section.
display 'foo'
goback.
we already have JAVA classes to map some-item to subordinate data items in JAVA, and to supply the whole thing as a byte array.
So in JAVA we need to call 'COBOL' passing a reference (pointer) to our byte array.
Then, if the COBOL program changes storage within the some-item , we see it back in JAVA when the call is finished.
So, I don't need to access working-storage items directly, just pass the reference pointer of our byte array to the called program. SWIG seems overkill for this at first glance.
Works quite well with Micro Focus, but they have helper classes in a jar to make this easy (new ParameterList, and then adding POINTER values to the call parameter list).
I don't know JAVA half as well as COBOL though, an example or two, or some documentation on the topic would be super.
Last edit: Bill Woodger 2016-01-15
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I didn't delete it. I was really confused as to why I could see 5 posts in the thread, last one by me, but no actual post. My profile page shows me having made the post, but yet ... no post. And I can't remember what I wrote exactly. I don't mind if you post it again, or, I can write another one.
I think I'll have to start Ctrl-A-C-V these postings to my text editor :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
And I'd recommend a second look at SWIG. If the objective is calling into COBOL, SWIG is the ticket. As it is all compiled to native library calls, the overhead baggage is pretty small. The SWIG tooling is rather large, as it covers a lot of bases, but the end product is pretty close to what a hand crafted solution would end up being, just easier on the brain.
Why don't you try SWIG, i have attached the example on FAQ by Brian just do make java, java main. then you can take it from there when i was looking at the example my only challenge was passing data to cobol from java and back to java as the examples only invokes cobol from java.
I made this example of calling GnuCOBOL program from Java using JNA. I built it with JNA 4.2.1 and Java 8.
COBOL program, cobsubtest.cbl
identificationdivision.program-id.cobsubtest.datadivision.linkagesection.01 PassedParameterpic X(72).proceduredivisionusingbyreference PassedParameter.A-MainSection.display 'Starting cobsubtest.cbl'display 'Called With ['PassedParameter']'move2 TOreturn-code.goback.
JAVA program jnacob.java:
importcom.sun.jna.*;/* * libcob interface, initialising GnuCOBOL run time */interfacelibcobextendsLibrary{libcobINSTANCE=(libcob)Native.loadLibrary("cob",libcob.class);voidcob_init(intargc,Pointerargv);}/* * COBOL program interface, single program */interfacesubtestextendsLibrary{subtestINSTANCE=(subtest)Native.loadLibrary("cobsubtest",subtest.class);intcobsubtest(PointeraValue);}publicclassjnacob{publicstaticvoidmain(String[]args){/* * try and initialise the GnuCOBOL run time * calling cob_init with no parameters */try{libcob.INSTANCE.cob_init(0,null);}catch(UnsatisfiedLinkErrore){System.out.println("Libcob Exception"+e);}/* * call a GnuCOBOL program, passing a PIC X(72) * space filled */try{// JAVA stringStringstringThing=newString("We Did It!");// make a Pointer and space fill// we use -1 on the pointer write to strip// the C null string terminatorPointerpointer;pointer=newMemory(72);bytespace=32;pointer.setMemory(0,72,space);byte[]data=Native.toByteArray(stringThing);pointer.write(0,data,0,data.length-1);// call the GnuCOBOL programintrc=subtest.INSTANCE.cobsubtest(pointer);// display return-codeSystem.out.print("COBOL Return Code ");System.out.println(rc);}catch(UnsatisfiedLinkErrore){System.out.println("subtest Exception"+e);}}}
Build and execute:
Need to have jna-4.2.1.jar in current directory (or, elsewhere, modify classpath as appropriate)
identificationdivision.program-id.cobsubtest2.datadivision.linkagesection.01 PassedParameterpic X(72).proceduredivisionusingbyreference PassedParameter.A-MainSection.display 'Starting cobsubtest2:'display 'Called With ['PassedParameter']'move8 TOreturn-code.goback.
jnacob.java
importcom.sun.jna.*;/* * libcob interface, initialising GnuCOBOL run time */interfacelibcobextendsLibrary{libcobINSTANCE=(libcob)Native.loadLibrary("cob",libcob.class);voidcob_init(intargc,Pointerargv);}/* * first COBOL program interface, single program */interfacesubtestextendsLibrary{subtestINSTANCE=(subtest)Native.loadLibrary("cobsubtest",subtest.class);intcobsubtest(PointeraValue);}/* * second COBOL program interface, single program */interfacesubtest2extendsLibrary{subtest2INSTANCE=(subtest2)Native.loadLibrary("cobsubtest2",subtest2.class);intcobsubtest2(PointeraValue);}publicclassjnacob{publicstaticvoidmain(String[]args){/* * try and initialise the GnuCOBOL run time * calling cob_init with no parameters */try{libcob.INSTANCE.cob_init(0,null);}catch(UnsatisfiedLinkErrore){System.out.println("Libcob Exception"+e);}/* * call a GnuCOBOL program, passing a PIC X(72) * space filled */try{// JAVA stringStringstringThing=newString("We Did It!");// make a Pointer and space fillPointerpointer;pointer=newMemory(72);bytespace=32;pointer.setMemory(0,72,space);byte[]data=Native.toByteArray(stringThing);pointer.write(0,data,0,data.length-1);intrc;// call the GnuCOBOL programrc=subtest.INSTANCE.cobsubtest(pointer);// display return-codeSystem.out.print("COBOL Return Code ");System.out.println(rc);// call the second testrc=subtest2.INSTANCE.cobsubtest2(pointer);System.out.print("COBOL Return Code ");System.out.println(rc);}catch(UnsatisfiedLinkErrore){System.out.println("subtest Exception"+e);}}}
Result:
Starting cobsubtest.cbl
Called With [We Did It! ]
COBOL Return Code 2
Starting cobsubtest2:
Called With [We changed it! ]
COBOL Return Code 8
Last edit: Simon Sobisch 2016-01-18
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
Anonymous
-
2020-06-24
In this example i can see the data being passed between two cobol programs,
Here i can see the java program accepting the return-code from cobol program rc=subtest.INSTANCE.cobsubtest(pointer);
But now i want to know how do we access this or print or display data/value inside pointer on our java program? i want to pass value to cobol program the receive it and then use it on my java program right now i dont know how to access the data inside pointer
Can someone please help me?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tons of access methods, read(...) is likely what you are looking for.
Cheers,
Blue
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
Anonymous
-
2020-06-25
Thanks Brian,
I just hacked this around, here is a working version.
importcom.sun.jna.*;/** libcob interface, initialising GnuCOBOL run time*/interfacelibcobextendsLibrary{libcobINSTANCE=(libcob)Native.loadLibrary("libcob-4",libcob.class);voidcob_init(intargc,Pointerargv);}/** first COBOL program interface, single program*/interfacesubtestextendsLibrary{subtestINSTANCE=(subtest)Native.loadLibrary("cobsubtest",subtest.class);intcobsubtest(PointeraValue);}/** second COBOL program interface, single program*/interfacesubtest2extendsLibrary{subtest2INSTANCE=(subtest2)Native.loadLibrary("cobsubtest2",subtest2.class);intcobsubtest2(PointeraValue);}publicclassjnacob{publicstaticvoidmain(String[]args){/* * try and initialise the GnuCOBOL run time * calling cob_init with no parameters */try{libcob.INSTANCE.cob_init(0,null);}catch(UnsatisfiedLinkErrore){System.out.println("Libcob Exception"+e);}/* * call a GnuCOBOL program, passing a PIC X(72) * space filled */try{// JAVA stringStringstringThing=newString("We Did It!");// make a Pointer and space fillPointerpointer;pointer=newMemory(72);bytespace=32;pointer.setMemory(0,72,space);byte[]data=Native.toByteArray(stringThing);pointer.write(0,data,0,data.length-1);intrc;// call the GnuCOBOL programrc=subtest.INSTANCE.cobsubtest(pointer);byte[]data_2=newbyte[72];((Pointer)pointer).read(0,data_2,0,data_2.length);Stringcoboldata=newString(data_2);System.out.println("data from cobol : "+coboldata);// display return-codeSystem.out.print("COBOL Return Code ");System.out.println(rc);// call the second testrc=subtest2.INSTANCE.cobsubtest2(pointer);System.out.print("COBOL Return Code ");System.out.println(rc);}catch(UnsatisfiedLinkErrore){System.out.println("subtest Exception"+e);}}}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That program uses some old deprecated method to load the library, here is an improved program.
importcom.sun.jna.*;/** libcob interface, initialising GnuCOBOL run time*/interfacelibcobextendsLibrary{libcobINSTANCE=Native.load("libcob-4",libcob.class);voidcob_init(intargc,Pointerargv);}/** first COBOL program interface, single program*/interfacesubtestextendsLibrary{subtestINSTANCE=Native.load("cobsubtest",subtest.class);intcobsubtest(PointeraValue);}/** second COBOL program interface, single program*/interfacesubtest2extendsLibrary{subtest2INSTANCE=Native.load("cobsubtest2",subtest2.class);intcobsubtest2(PointeraValue);}publicclassjnacob{publicstaticvoidmain(String[]args){/* * try and initialise the GnuCOBOL run time * calling cob_init with no parameters */try{libcob.INSTANCE.cob_init(0,null);}catch(UnsatisfiedLinkErrore){System.out.println("Libcob Exception"+e);}/* * call a GnuCOBOL program, passing a PIC X(72) * space filled */try{// JAVA stringStringstringThing=newString("We Did It!");// make a Pointer and space fillPointerpointer;pointer=newMemory(72);bytespace=32;pointer.setMemory(0,72,space);byte[]data=Native.toByteArray(stringThing);pointer.write(0,data,0,data.length-1);intrc;// call the GnuCOBOL programrc=subtest.INSTANCE.cobsubtest(pointer);byte[]data_2=newbyte[72];pointer.read(0,data_2,0,data_2.length);Stringcoboldata=newString(data_2);System.out.println("data from cobol : ["+coboldata+"]");// display return-codeSystem.out.print("COBOL Return Code ");System.out.println(rc);// call the second testrc=subtest2.INSTANCE.cobsubtest2(pointer);System.out.print("COBOL Return Code ");System.out.println(rc);}catch(UnsatisfiedLinkErrore){System.out.println("subtest Exception"+e);}}}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not really a JAVA programmer (I know it basically, but not steeped in it on a daily basis), I'm sure some will throw their hands up in horror, especially around the string handling and interfaces.
I am wondering about compiling many .cbl files to a single .so though, as that would cut down the JNA glue. It might be fine for these small tests, but my full app has over 3,500 cobol modules.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Do all the 3,500 need to talk to JAVA? Even if so, what would be against a COBOL subprogram acting as an interface, the COBOL programs CALL that, it does the JAVA stuff, and returns from whence it came with whatever action completed and whatever result produced.
Did you write all the COBOL programs yourself?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
View and moderate all "Help getting started" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
Hi,
Is it possible to call GNUCobol from java? or to call Java from cobol?
Yes.
GnuCOBOL can easily link to anything C, and JNI is available. If you are doing a large integration, the SWIG tool would likely be very smart place to start. COBOL to C, then SWIG the C to and from Java.
There is a grand contribution to GnuCOBOL by László Erdős, COBJAPI, direct access to AWT features from COBOL user defined functions. Very well documented, loads of examples.
http://sourceforge.net/p/open-cobol/discussion/contrib/thread/cf38bb95/
Cheers
View and moderate all "Help getting started" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
Thanks Brian,
i have looked at SWIG looks like this is going to be easier than i thought.
Yeah, it does make it pretty easy. I'll put a sample in the FAQ. A couple of issues.
And the big one:
Cheers,
Brian
I'm very interested also in being able to call Gnu COBOL modules from Java with JNI
Our current application uses Micro Focus with its runtime system jar.
I suspect though, that's overkill for what we need.
We need to instantiate a COBOL runtime, then invoke a module passing LINKAGE items as byte arrays.
So, for example we might have
LINKAGE
01 some-item
03 ... PIC
03 ... PIC
03 ... PIC
procedure division using some-item.
a-main section.
display 'foo'
goback.
we already have JAVA classes to map some-item to subordinate data items in JAVA, and to supply the whole thing as a byte array.
So in JAVA we need to call 'COBOL' passing a reference (pointer) to our byte array.
Then, if the COBOL program changes storage within the some-item , we see it back in JAVA when the call is finished.
So, I don't need to access working-storage items directly, just pass the reference pointer of our byte array to the called program. SWIG seems overkill for this at first glance.
Works quite well with Micro Focus, but they have helper classes in a jar to make this easy (new ParameterList, and then adding POINTER values to the call parameter list).
I don't know JAVA half as well as COBOL though, an example or two, or some documentation on the topic would be super.
Was Gary Cowell's post deleted on purpose? By mistake? Or is this a SourceForge glitch? The summary screen still shows a link (though it won't once I make this post) and I got an email copy, so can reproduce his entry, but I'm not seeing it here. Don't want to just add it back in if it was deleted on purpose.
Curious,
Brian
Last edit: Brian Tiffin 2016-01-15
Brian, I can see it now, and I could see it seven hours ago just befeore I got to bed. It is marked as "20 hours ago"
I can't see it. Please repost it if you see it.
Repost from copy/paste of what I can see from original post by Gary Cowel.
Odd. I've noticed something possibly simimlar (appear on summary page, not in list of posts within acrual area) with some anonymous posts over the last few months. Sorts itself out after some time with those, so didn't think much of it. Could be a different issue.
I'm very interested also in being able to call Gnu COBOL modules from Java with JNI
Our current application uses Micro Focus with its runtime system jar.
I suspect though, that's overkill for what we need.
We need to instantiate a COBOL runtime, then invoke a module passing LINKAGE items as byte arrays.
So, for example we might have
LINKAGE
01 some-item
03 ... PIC
03 ... PIC
03 ... PIC
procedure division using some-item.
a-main section.
display 'foo'
goback.
we already have JAVA classes to map some-item to subordinate data items in JAVA, and to supply the whole thing as a byte array.
So in JAVA we need to call 'COBOL' passing a reference (pointer) to our byte array.
Then, if the COBOL program changes storage within the some-item , we see it back in JAVA when the call is finished.
So, I don't need to access working-storage items directly, just pass the reference pointer of our byte array to the called program. SWIG seems overkill for this at first glance.
Works quite well with Micro Focus, but they have helper classes in a jar to make this easy (new ParameterList, and then adding POINTER values to the call parameter list).
I don't know JAVA half as well as COBOL though, an example or two, or some documentation on the topic would be super.
Last edit: Bill Woodger 2016-01-15
Thanks, Bill.
Apologies to Gary. It's an anomaly, Gary, hopefully not to happen again.
Cheers,
Brian
I didn't delete it. I was really confused as to why I could see 5 posts in the thread, last one by me, but no actual post. My profile page shows me having made the post, but yet ... no post. And I can't remember what I wrote exactly. I don't mind if you post it again, or, I can write another one.
I think I'll have to start Ctrl-A-C-V these postings to my text editor :)
Have you seen COBJAPI yet, Gary? László did a superb job at easing access into Java space with User Defined Functions.
http://sourceforge.net/p/open-cobol/contrib/HEAD/tree/trunk/tools/cobjapi/
It's one option. There are others.
And I'd recommend a second look at SWIG. If the objective is calling into COBOL, SWIG is the ticket. As it is all compiled to native library calls, the overhead baggage is pretty small. The SWIG tooling is rather large, as it covers a lot of bases, but the end product is pretty close to what a hand crafted solution would end up being, just easier on the brain.
http://open-cobol.sourceforge.net/faq/index.html#does-gnucobol-work-with-swig has a Java sample, and the output binaries are pretty tight. I'll try and remember to add some directory size listings to that entry soon.
The whole thing breaks down if you want to leverage Java from COBOL, as that is not the goal of the SWIG tool, I'd look to COBJAPI for that.
Cheers,
Brian
Also, I've started to look into JNA rather than JNI. JNA looks easier to code for. I think I'll do a couple of simple examples, and see how it goes.
+1 on JNA being an avenue worth travelling.
I might even try and put a sample entry in the FAQ someday soon.
Cheers,
Brian
Hi Gary,
Why don't you try SWIG, i have attached the example on FAQ by Brian just do make java, java main. then you can take it from there when i was looking at the example my only challenge was passing data to cobol from java and back to java as the examples only invokes cobol from java.
Last edit: Oscar 2016-01-15
Will check it out, thanks
I made this example of calling GnuCOBOL program from Java using JNA. I built it with JNA 4.2.1 and Java 8.
COBOL program, cobsubtest.cbl
JAVA program jnacob.java:
Build and execute:
Need to have jna-4.2.1.jar in current directory (or, elsewhere, modify classpath as appropriate)
Will be doing more work to show COBOL sub routines mutating storage, and sharing that storage between COBOL modules.
Hope this helps someone get started.
Last edit: Simon Sobisch 2016-01-18
Updated now with mutation showing between sub programs (didn't really expect this wouldn't work, but it's worth showing):
cobsubtest.cbl
cobsubtest2.cbl
jnacob.java
Result:
Last edit: Simon Sobisch 2016-01-18
In this example i can see the data being passed between two cobol programs,
Here i can see the java program accepting the return-code from cobol program
rc=subtest.INSTANCE.cobsubtest(pointer);
But now i want to know how do we access this or print or display data/value inside
pointer
on our java program? i want to pass value to cobol program the receive it and then use it on my java program right now i dont know how to access the data insidepointer
Can someone please help me?
See https://java-native-access.github.io/jna/4.2.1/com/sun/jna/Pointer.html
Tons of access methods,
read(...)
is likely what you are looking for.Cheers,
Blue
Thanks Brian,
I just hacked this around, here is a working version.
That program uses some old deprecated method to load the library, here is an improved program.
Thank you, very nice sample for the FAQ. It's likely worth to be put to https://sourceforge.net/p/open-cobol/contrib/HEAD/tree/trunk/samples/JAVA_using_COBOL
BTW: I've added syntax highlighting to your posts via
::language
and suggest you have a look at this via "Edit Post" :-)I notice the syntax markers, thanks.
I'm not really a JAVA programmer (I know it basically, but not steeped in it on a daily basis), I'm sure some will throw their hands up in horror, especially around the string handling and interfaces.
I am wondering about compiling many .cbl files to a single .so though, as that would cut down the JNA glue. It might be fine for these small tests, but my full app has over 3,500 cobol modules.
Do all the 3,500 need to talk to JAVA? Even if so, what would be against a COBOL subprogram acting as an interface, the COBOL programs CALL that, it does the JAVA stuff, and returns from whence it came with whatever action completed and whatever result produced.
Did you write all the COBOL programs yourself?