Can I call a Java class function from Progress ?

kkumarc

New Member
Hello,

Is there a way i can call a Java class from Progress? I don't want to use OSCommand function though. Any other better method to invoke Java functions residing in a class?

What i am trying to do is to call the Memcached Java APIs from Progress, since i do not have a Progress equivalent API for Memcached.

regards
krishna
 

TomBascom

Curmudgeon
Progress can call external shared libraries but Progress is also aggressively single threaded. That often means trouble when trying to call Java and the ilk.
 

kkumarc

New Member
Yeah Marian, I am also trying to adopt the same approach. What i have done is made a shared library out of libmemcached code and tried calling from Progress. Unfortunately I am getting an error "SYSTEM ERROR: Memory violation. (49)"

The code snipped which i tried is as given below:
v-server = "--SERVER=<ip address of the memcached server> ".
ASSIGN v-county = "Country"
v-county-val = "India".
SET-SIZE(v-han) = 1000.
SET-SIZE(v-han1) = 10.

RUN memcached(INPUT v-server,
OUTPUT v-han).
MESSAGE 'v-han' STRING(v-han).

run memcached_set(input v-han,
INPUT v-county,
INPUT v-county-val).

Value of 'v-han' is blank so i guess that is the reason why memcached_set is giving that memory allocation error.
regards
krishna
 

Marian EDU

Member
without seeing the procedure external declarations for memcached and memcached_set it's kinda hard to tell why do you get that error...

v-han looks like being a memptr variable (as you use set-size on it), while I do expect the memcached procedure to have a return parameter of type 'long' - the pointer to the memcached structure that you can later use to get/set keys and eventually free when done with it.
 

kkumarc

New Member
Dear Marian,
I have sent an email with the code which we have used. Kindly go through it and suggest.

Thanks
Krishna
without seeing the procedure external declarations for memcached and memcached_set it's kinda hard to tell why do you get that error...

v-han looks like being a memptr variable (as you use set-size on it), while I do expect the memcached procedure to have a return parameter of type 'long' - the pointer to the memcached structure that you can later use to get/set keys and eventually free when done with it.
 

kkumarc

New Member
Dear Tamhas,
I downloaded the jpjvm.zip file and found jpjvm.dll inside. Can this be used in Linux environment? I mean can we generate a jpjvm.so file using a make script? Any pointers would be helpful.
regards
krishna
 

Marian EDU

Member
Dear Marian,
I have sent an email with the code which we have used. Kindly go through it and suggest.

Thanks
Krishna

I've only found a 32 bits binary for an older version of libmemcached (libmemcached.so.6) which doesn't have the memcached entry point you seems to be using in libmemcached.so.8. Not sure if the fact that I'm using the 32bits library on a 64bits machine with Ubuntu 64 could be the cause of my issue but it looks like when servers get's added to the memcached structure then calling free on it, or simply servers_reset (that is supposed to free the servers list), will result in a GPF... my guess is that there is a free on a memory zone that was previously allocated by the Progress client not the library, might be simply a bug in libmemcached :)

Anyway, you can try to adapt the code you have for the newest version... see the use of long data-type and the return parameter.

Code:
&global-define memcache-lib  "/tmp/memc/libmemcached.so.6"
&global-define memcache-call PASCAL
 
procedure memcached_create external {&memcache-lib} {&memcache-call}:
   define input  parameter h-memc     as long      no-undo.
   define return parameter h-new      as long      no-undo.
end procedure.


procedure memcached_server_add external {&memcache-lib} {&memcache-call}:
  define input  parameter h-memc     as long      no-undo.
  define input  parameter srvHost    as character no-undo.
  define input  parameter srvPort    as long      no-undo.
  define return parameter retVal     as long      no-undo.
end procedure.


procedure memcached_servers_reset external {&memcache-lib} {&memcache-call}:
  define input parameter h-memc as long no-undo.
end.
     
procedure memcached_free external {&memcache-lib} {&memcache-call}:
  define input parameter h-memc as long no-undo.


end.


procedure memcached_get external {&memcache-lib} {&memcache-call}:
    define input  parameter h-memc as long      no-undo.
    define input  parameter strKey as character no-undo.
    define input  parameter keyLen as long      no-undo.
    define input  parameter valLen as long      no-undo.
    define input  parameter flags  as long      no-undo.
    define input  parameter h-err  as long      no-undo.
    define return parameter valStr as character no-undo.
         
end procedure.                                                                  


procedure memcached_set external {&memcache-lib} {&memcache-call}:
    define input  parameter h-memc as long      no-undo.
    define input  parameter strKey as character no-undo.
    define input  parameter keyLen as long      no-undo.
    define input  parameter strVal as character no-undo.
    define input  parameter valLen as long      no-undo.
    define input  parameter fTime  as long      no-undo.
    define input  parameter fExp   as long      no-undo.
    define return parameter retVal as long      no-undo.


end procedure.


def var h-memc as integer   no-undo.
def var retVal as integer   no-undo.
def var keyVal as character no-undo.
def var memKey as memptr    no-undo.
def var memVal as memptr    no-undo.
 
run memcached_create (0, output h-memc).


message h-memc view-as alert-box.
run memcached_server_add(h-memc, "localhost", 11211, output retVal).


message 'retVal' skip retVal view-as alert-box.


run memcached_set (h-memc, "toto", 4, 
                  "fifi", 4, 0, 0, output retVal) 
    no-error.
message 'set' skip retVal view-as alert-box.  


run memcached_servers_reset(h-memc) no-error.
message 'reset' view-as alert-box.      
run memcached_free( h-memc) no-error.


message 'end' view-as alert-box.
 

kkumarc

New Member
Thanks a lot Marian. I will try and let you know.
Meanwhile is it possible to get libmemcached.so.6 version of the file?

regards
krishna
I've only found a 32 bits binary for an older version of libmemcached (libmemcached.so.6) which doesn't have the memcached entry point you seems to be using in libmemcached.so.8. Not sure if the fact that I'm using the 32bits library on a 64bits machine with Ubuntu 64 could be the cause of my issue but it looks like when servers get's added to the memcached structure then calling free on it, or simply servers_reset (that is supposed to free the servers list), will result in a GPF... my guess is that there is a free on a memory zone that was previously allocated by the Progress client not the library, might be simply a bug in libmemcached :)

Anyway, you can try to adapt the code you have for the newest version... see the use of long data-type and the return parameter.

Code:
&global-define memcache-lib  "/tmp/memc/libmemcached.so.6"
&global-define memcache-call PASCAL
 
procedure memcached_create external {&memcache-lib} {&memcache-call}:
   define input  parameter h-memc     as long      no-undo.
   define return parameter h-new      as long      no-undo.
end procedure.


procedure memcached_server_add external {&memcache-lib} {&memcache-call}:
  define input  parameter h-memc     as long      no-undo.
  define input  parameter srvHost    as character no-undo.
  define input  parameter srvPort    as long      no-undo.
  define return parameter retVal     as long      no-undo.
end procedure.


procedure memcached_servers_reset external {&memcache-lib} {&memcache-call}:
  define input parameter h-memc as long no-undo.
end.
     
procedure memcached_free external {&memcache-lib} {&memcache-call}:
  define input parameter h-memc as long no-undo.


end.


procedure memcached_get external {&memcache-lib} {&memcache-call}:
    define input  parameter h-memc as long      no-undo.
    define input  parameter strKey as character no-undo.
    define input  parameter keyLen as long      no-undo.
    define input  parameter valLen as long      no-undo.
    define input  parameter flags  as long      no-undo.
    define input  parameter h-err  as long      no-undo.
    define return parameter valStr as character no-undo.
         
end procedure.                                                                  


procedure memcached_set external {&memcache-lib} {&memcache-call}:
    define input  parameter h-memc as long      no-undo.
    define input  parameter strKey as character no-undo.
    define input  parameter keyLen as long      no-undo.
    define input  parameter strVal as character no-undo.
    define input  parameter valLen as long      no-undo.
    define input  parameter fTime  as long      no-undo.
    define input  parameter fExp   as long      no-undo.
    define return parameter retVal as long      no-undo.


end procedure.


def var h-memc as integer   no-undo.
def var retVal as integer   no-undo.
def var keyVal as character no-undo.
def var memKey as memptr    no-undo.
def var memVal as memptr    no-undo.
 
run memcached_create (0, output h-memc).


message h-memc view-as alert-box.
run memcached_server_add(h-memc, "localhost", 11211, output retVal).


message 'retVal' skip retVal view-as alert-box.


run memcached_set (h-memc, "toto", 4, 
                  "fifi", 4, 0, 0, output retVal) 
    no-error.
message 'set' skip retVal view-as alert-box.  


run memcached_servers_reset(h-memc) no-error.
message 'reset' view-as alert-box.      
run memcached_free( h-memc) no-error.


message 'end' view-as alert-box.
 

kkumarc

New Member
Thank you Marian, your code executes without any error and messages are properly displayed. But when i try to retrieve the value stored using the same key "toto" it is giving same memory violation error.

def var retValStr as character no-undo.
run memcached_get (h-memc, "toto", 4,
4, 0, 0, output retValStr)
message 'get' skip retValStr view-as alert-box.

Any idea what could be wrong here?

regards
krishna
 

Marian EDU

Member
run memcached_get (h-memc, "toto", 4,
4, 0, 0, output retValStr).

Any idea what could be wrong here?

well, didn't had the time to look into get function yesterday... left as an exercise for the reader ;)

however, looking again at it this morning saw the obvious thing that I've forgot to specify persistent which probably was the cause of GPF when trying to free the memcached structure at the end... there is also the working get function and abl wrappers for get/set procedures to make it easier for our abl programmers :)

hope to find some time to polish it and make it a small project in case anyone else needs something like that...

Code:
&global-define memcache-lib  "/tmp/memc/libmemcached.so.6"
&global-define memcache-call CDECL
&global-define MEMCACHED_SUCCESS 0
 
procedure memcached_create external {&memcache-lib} persistent {&memcache-call}:
   define input  parameter h-memc     as long      no-undo.
   define return parameter h-new      as long      no-undo.
end procedure.


procedure memcached_server_add external {&memcache-lib} persistent {&memcache-call}:
  define input  parameter h-memc     as long      no-undo.
  define input  parameter srvHost    as character no-undo.
  define input  parameter srvPort    as long      no-undo.
  define return parameter retVal     as long      no-undo.
end procedure.


procedure memcached_servers_reset external {&memcache-lib} persistent {&memcache-call}:
  define input parameter h-memc as long no-undo.
end.
     
procedure memcached_free external {&memcache-lib} persistent {&memcache-call}:
  define input parameter h-memc as long no-undo.


end.


procedure memcached_get external {&memcache-lib} persistent {&memcache-call}:
    define input  parameter h-memc as long      no-undo.
    define input  parameter strKey as character no-undo.
    define input  parameter keyLen as long      no-undo.
    define input  parameter valLen as memptr    no-undo.
    define input  parameter flags  as memptr    no-undo.
    define input  parameter h-err  as memptr    no-undo.
    define return parameter valStr as memptr    no-undo.
         
end procedure.                                                                  


procedure memcached_set external {&memcache-lib} persistent {&memcache-call}:
    define input  parameter h-memc as long      no-undo.
    define input  parameter strKey as character no-undo.
    define input  parameter keyLen as long      no-undo.
    define input  parameter strVal as character no-undo.
    define input  parameter valLen as long      no-undo.
    define input  parameter fTime  as long      no-undo.
    define input  parameter fExp   as long      no-undo.
    define return parameter retVal as long      no-undo.


end procedure.


procedure memcached_get_key:
    define input  parameter h-memc as integer   no-undo.
    define input  parameter strKey as character no-undo.
    define output parameter strVal as character no-undo initial ?.
    
    def var memLen as memptr    no-undo.
    def var memFlg as memptr    no-undo.
    def var memErr as memptr    no-undo.
    def var memVal as memptr    no-undo.


    set-size(memLen) = 4.
    set-size(memFlg) = 4.
    set-size(memErr) = 4.
    set-size(memVal) = 0.
    put-long(memLen, 1) = 0.
    put-long(memFlg, 1) = 0.
    put-long(memErr, 1) = 0.


    run memcached_get(h-memc, strKey, length(strKey, 'raw'), 
                      memLen, memFlg, memErr,
                      output memVal).
    
    if get-long(memErr, 1) eq 0 and
       get-long(memLen, 1) gt 0 then
       strVal = get-string(memVal, 1, get-long(memLen, 1)).
    
    set-size(memLen) = 0.
    set-size(memFlg) = 0.
    set-size(memErr) = 0.    
    set-size(memVal) = 0.
     
end procedure.


procedure memcached_set_key:
    define input  parameter h-memc   as integer   no-undo.
    define input  parameter strKey   as character no-undo.
    define input  parameter strVal   as character no-undo.
    define input  parameter expTime  as integer   no-undo.
    define input  parameter optFlag  as integer   no-undo.
    define output parameter retVal   as logical   no-undo.
    
    define variable retCode as integer no-undo.
 
    run memcached_set (h-memc, strKey, length(strKey, 'raw'), 
                       strVal, length(strVal, 'raw'), expTime, optFlag, 
                       output retCode).
    
    retVal = retCode eq {&MEMCACHED_SUCCESS}.
end procedure.




def var h-memc  as integer   no-undo.
def var retCode as integer   no-undo.
def var retVal  as logical   no-undo.
def var keyVal  as character no-undo.
 
run memcached_create (0, output h-memc).


message h-memc view-as alert-box.
run memcached_server_add(h-memc, "localhost", 11211, output retCode).


message 'retVal' skip retCode view-as alert-box.


run memcached_set_key (h-memc, "toto", "tuareg", 60, 0, output retVal).
message 'set' skip retVal view-as alert-box.


run memcached_get_key (h-memc, "toto", output keyVal).
message 'get' skip keyVal view-as alert-box.


run memcached_free( h-memc) no-error.
message 'end' view-as alert-box.
 

kkumarc

New Member
Dear Marian,
retCode is coming as 3 for set for the following code. So that means set is not working properly?

run memcached_set (h-memc, strKey, length(strKey, 'raw'),
strVal, length(strVal, 'raw'), expTime, optFlag,
output retCode).

retVal = retCode eq {&MEMCACHED_SUCCESS}.

Thanks
Krishna
 

Marian EDU

Member
retCode is coming as 3 for set for the following code. So that means set is not working properly?

no, it just means you can't connect to the memcached server (see the enum below, 3 means MEMCACHED_CONNECTION_FAILURE).

you do have the server started on localhost (default port is 11211) do you? :)
try to connect to it using telnet and see if you get to connect... telnet localhost 11211

Code:
enum memcached_return_t {
  MEMCACHED_SUCCESS,
  MEMCACHED_FAILURE,
  MEMCACHED_HOST_LOOKUP_FAILURE, // getaddrinfo() and getnameinfo() only
  MEMCACHED_CONNECTION_FAILURE,
  ...
 

kkumarc

New Member
Thanks a lot Marian, you made my day.

Problem was that yesterday, i binded the server to the explicit server ip. So today i forgot to change localhost in your code. Sorry for the inconvenience caused. Really appreciate the help provided. I owe you a treat :eek:

regards
krishna
 
Top