ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Returning values from a java call to an RPG program?

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Returning values from a java call to an RPG program?

    Ok.

    I'm officially at my wits end.

    I've written a java class that accepts two strings and returns a string. Here is the prototype I've written for it in the RPG program:
    Code:
    d ResendOrder     pr              o   extproc(*JAVA:                             
    d                                     'com.DelMonte.WMS_BPCS_Integrator.ex-      
    d                                     ecutable.ResendOrder':'main')              
    d                                     class(*JAVA:'java.lang.String')            
    d                                     static                                     
    d                                 o   class(*JAVA:'java.lang.String')            
    d                                     const                                      
    d                                 o   class(*JAVA:'java.lang.String')            
    d                                     const
    Here's the procedure call:

    Code:
    ReturnMsg=ResendOrder(string(wmfac):string(charOrd)); 
    
    (ReturnMsg is defined as follows:
    
    d ReturnMsg       s               o   class(*JAVA:'java.lang.String'))
    Here's the error I get when I try to run it:
    Code:
    Message ID . . . . . . :   RNX0301                                             
    Date sent  . . . . . . :   03/08/11      Time sent  . . . . . . :   10:22:34   
                                                                                   
    Message . . . . :   Java exception received when calling Java method.          
                                                                                   
    Cause . . . . . :   RPG procedure GWBA09D5 in program MXMLIB/GWBA09D5 received 
      Java exception "java.lang.NoSuchMethodError: main" when calling [B][COLOR="red"]method       
      "main" with signature                                                        
      "(Ljava.lang.String;Ljava.lang.String; )Ljava.lang.String;" [/COLOR][/B]in class          
      "com.WMS_BPCS_Integrator.executable.ResendOrder".
    NOW HERE'S THE FUNNY PART:

    When I pull up the class with javap -s, here's what I get:
    Code:
    public class com..WMS_BPCS_Integrator.executable.ResendOrder extends
    java.lang.Object{                                                           
    public com.WMS_BPCS_Integrator.executable.ResendOrder();           
      Signature: ()V                                                            
    [B][COLOR="red"]public static java.lang.String main(java.lang.String, java.lang.String);    
      Signature: (Ljava/lang/String;Ljava/lang/String; )Ljava/lang/String;   [/COLOR][/B]    
    }
    Press ENTER to end terminal session.

    Note the parts bolded and in red? Those match.

    So...is it possible to actually invoke a java class in an RPG program and return a value, or am I just banging my head against the wall for nothing?

    Thanks!

  • #2
    Re: Returning values from a java call to an RPG program?

    yes you can return a java string object (or other java object for that matter). are you sure that your classpath is set correctly? (note: i'm not a java guy but i've integrated some RPG with Java so i might be off-base)
    I'm not anti-social, I just don't like people -Tommy Holden

    Comment


    • #3
      Re: Returning values from a java call to an RPG program?

      here's some working code i have:
      Code:
      diTextPhrase      s               o   Class(*JAVA                
      d                                     :'com.lowagie.text.Phrase')
       // this is simply *java.lang.string
      dworkString       s                   like(jString)
      dworkPhrase       s                   like(iTextPhrase)
       /free
      
         workString = new_String(' ');             
         workPhrase = new_TextPhrase( workString );
         // now workPhrase is a java object of type iTextPhrase
      I'm not anti-social, I just don't like people -Tommy Holden

      Comment


      • #4
        Re: Returning values from a java call to an RPG program?

        Yes, the classpath seems correct. It was the first thing I checked. I added a character to the class name in the prototype and ran it, and I received a class not found error, not a method not found error.

        All the documentation I've found tells me that, with this error, to make sure that what I'm sending and receiving matches what's being sent and received by the class.

        I have no idea how to move forward with this. I've tried every combination I can think of.

        Comment


        • #5
          Re: Returning values from a java call to an RPG program?

          The issue swirls around the returning value. If I remove the return value from both the prototype and the class, it runs without error.

          Which means I might have to just have the class write to a file or data area somewhere and then have the RPG program read from that. It's an ugly, cludgy way to do it, but I don't seem to have any other options.

          Comment


          • #6
            Re: Returning values from a java call to an RPG program?

            just a dumb question...did you instantiate the ReturnMsg object prior to the call to the procedure?
            I'm not anti-social, I just don't like people -Tommy Holden

            Comment


            • #7
              Re: Returning values from a java call to an RPG program?

              That was one of the things I tried as well. No affect...the same error.

              I'll throw it in there again, though, just to eliminate it as a problem.

              Comment


              • #8
                Re: Returning values from a java call to an RPG program?

                The relevent chunks of the program:
                Code:
                H specs:
                
                h bnddir('GWBA09BD') thread(*serialize)  
                
                Declarations:
                
                d ResendOrder     pr              o   extproc(*JAVA:                         
                d                                     'com.WMS_BPCS_Integrator.ex-  
                d                                     ecutable.ResendOrder':*constructor)  
                
                d main            pr              o   extproc(*JAVA:                           
                d                                     'com.DelMonte.WMS_BPCS_Integrator.ex-    
                d                                     ecutable.ResendOrder':'main')            
                d                                     class(*JAVA:'java.lang.String')          
                d                                     static                                   
                d                                 o   class(*JAVA:'java.lang.String')          
                d                                     const                                    
                d                                 o   class(*JAVA:'java.lang.String')          
                d                                     const                                    
                
                d string          pr              o   extproc(*JAVA:                 
                d                                             'java.lang.String':    
                d                                             *CONSTRUCTOR)          
                d value                      32000a   const varying                  
                
                d ReturnMsg       s               o   class(*JAVA:'java.lang.String')
                
                Procedure calls:
                
                callP SetEnvVar();   (this sets the home directory and class path)     
                callP ResendOrder();  
                ReturnMsg=main(string(wmfac):string(charOrd));

                Comment


                • #9
                  Re: Returning values from a java call to an RPG program?

                  there we go...now i have something to work with try this:
                  Code:
                  H specs:
                  
                  h bnddir('GWBA09BD') thread(*serialize)  
                  
                  Declarations:
                  
                  d ResendOrder     pr              o   extproc(*JAVA:                         
                  d                                     'com.WMS_BPCS_Integrator.ex-  
                  d                                     ecutable.ResendOrder':*constructor)  
                  [COLOR="red"]d                                     like(String)[/COLOR]
                  
                  d main            pr              o   extproc(*JAVA:                           
                  d                                     'com.DelMonte.WMS_BPCS_Integrator.ex-    
                  d                                     ecutable.ResendOrder':'main')            
                  d                                     class(*JAVA:'java.lang.String')          
                  d                                     static                                   
                  d                                 o   class(*JAVA:'java.lang.String')          
                  d                                     const                                    
                  d                                 o   class(*JAVA:'java.lang.String')          
                  d                                     const                                    
                  
                  d string          pr              o   extproc(*JAVA:                 
                  d                                             'java.lang.String':    
                  d                                             *CONSTRUCTOR)          
                  d value                      32000a   const varying    
                  [COLOR="red"]d Order              s                      Like(String)  [/COLOR]            
                  
                  d ReturnMsg       s               o   class(*JAVA:'java.lang.String')
                  
                  Procedure calls:
                  
                  callP SetEnvVar();   (this sets the home directory and class path)     
                  [COLOR="red"]String =  [/COLOR]ResendOrder();  
                  ReturnMsg=main([COLOR="red"]String:[/COLOR]string(wmfac):string(charOrd));
                  I'm not anti-social, I just don't like people -Tommy Holden

                  Comment


                  • #10
                    Re: Returning values from a java call to an RPG program?

                    I can't define ResendOrder like anything, because it's a constructor prototype.

                    When you say String, am I defining it like my string prototype, or like a string object?

                    Thanks!

                    Comment


                    • #11
                      Re: Returning values from a java call to an RPG program?

                      string like your prototype (which is a java string object incidentally) and you can define a constructor "like" as in:
                      Code:
                      dnew_InputStream  pr                  ExtProc(*JAVA              
                      d                                     :'java.io.InputStream'     
                      d                                     :*CONSTRUCTOR)             
                      d                                     like(jInputStream)
                      actually i don't think i've ever seen a RPG prototype for a Java object that didn't use like().
                      I'm not anti-social, I just don't like people -Tommy Holden

                      Comment


                      • #12
                        Re: Returning values from a java call to an RPG program?

                        See, need a object to hold a return value from Construction ..if you are not going to invoke static method , so main method should be called as a ........ (not sure what is the word.. )
                        This is how you going to invoke main methods in ResendOrder class from java
                        Code:
                        ResendOrder [COLOR="darkred"]ResendCLZ [/COLOR]= new ResendOrder();
                        String ReturnMsg = [COLOR="darkred"]ResendCLZ.[/COLOR]main("somevalue","somevalue")
                        RPG Conversion...

                        Code:
                        [COLOR="darkred"]d ResendCLZ       S               o   CLASS(*JAVA:                         
                        d                                     'com.WMS_BPCS_Integrator.ex-  
                        d                                     ecutable.ResendOrder')  [/COLOR]
                        
                        d ResendOrder     pr              o   extproc(*JAVA:                         
                        d                                     'com.WMS_BPCS_Integrator.ex-  
                        d                                     ecutable.ResendOrder':*constructor)  
                        
                        d main            pr              o   extproc(*JAVA:                           
                        d                                     'com.DelMonte.WMS_BPCS_Integrator.ex-    
                        d                                     ecutable.ResendOrder':'main')            
                        d                                     class(*JAVA:
                        d                                     'com.WMS_BPCS_Integrator.ex-  
                        d                                     ecutable.ResendOrder')           
                        d                                     
                        d                                 o   class(*JAVA:'java.lang.String')          
                        d                                     const                                    
                        d                                 o   class(*JAVA:'java.lang.String')          
                        d                                     const                                    
                        
                        d string          pr              o   extproc(*JAVA:                 
                        d                                             'java.lang.String':    
                        d                                             *CONSTRUCTOR)          
                        d value                      32000a   const varying                  
                        
                        d ReturnMsg       s               o   class(*JAVA:'java.lang.String')
                         /free
                             
                                  [COLOR="darkred"]ResendCLZ  [/COLOR]= ResendOrder();  
                                  ReturnMsg=main([COLOR="darkred"]ResendCLZ  [/COLOR]: string(wmfac):string(charOrd));
                        Enjoy...

                        Comment


                        • #13
                          Re: Returning values from a java call to an RPG program?

                          You don't call a static method for an object. E.g.
                          If you have a class called MyClass with a static method called myStaticMethod and a normal method called myNormalMethod then you would invoke these methods like this:
                          PHP Code:
                          MyClass myObj = new MyClass();
                          myObj.myNormalMethod();

                          MyClass.myStaticMethod(); 
                          So the static method is called as a standalone property of the class. Generally static methods are to be avoided in Java because they are not really object oriented. It usually means you have something a bit wrong with the design. The one big exception is the main method.

                          public static void main(String[] args){}

                          This method has special significance in Java as it is the entry point when a Java application is called. When you run a Java app you give it the class with the main method which must have this signature. Personally I would steer clear of creating a static main method with a different signature because it could lead to confusion. The Java compiler should allow it but it's confusing to people using the code. It may well even be the problem confusing the RPG? I wouldn't know without trying it myself.

                          The first post said the error was a NoSuchMethodError exception. The two problems that most often cause this are incorrect classpath or the JVM needing restarting. You say you are setting the classpath so this should be ok unless you have made a mistake? It's worth checking. You can be caught out sometimes if the classpath has more than one version of the class in it. This sometimes happens if the class/jar is in the system part of the classpath too. It could just as easily be a typo too!

                          The second part about restarting the JVM is another gotcha. If you run your Java interactively then the JVM is started for your interactive job and then the classes loaded into it. If you make a change and recompile your Java class then there will be a mismatch. The only thing you can do is to end the job by signing out and back in again before re-running it. Obviously if it's a batch job then you just end the job and start another.
                          Ben

                          Comment


                          • #14
                            Re: Returning values from a java call to an RPG program?

                            IT LIVES!!!!!

                            The prototype:
                            Code:
                            d ResendOrder     pr              o   static extproc(*JAVA:                  
                            d                                     'com.WMS_BPCS_Integrator.ex-  
                            d                                     ecutable.ResendOrder':'resendOrder')   
                            d                                     class(*JAVA:'java.lang.String')        
                            d                                 o   class(*JAVA:'java.lang.String')        
                            d                                     const                                  
                            d                                 o   class(*JAVA:'java.lang.String')        
                            d                                     const          
                            
                            The class definition:
                            
                            public class ResendOrder
                            {
                                public static String resendOrder(String Facility, String Order)
                                {...}
                            }
                            Two key things:

                            1. Both the prototype AND the method need to be defined as static.
                            2. You kind of need to, um, log off and log back in after you change the class.

                            Thank you everybody for your help!
                            Last edited by tomholden; March 9, 2011, 08:34 AM.

                            Comment


                            • #15
                              Re: Returning values from a java call to an RPG program?

                              umm...isn't that pretty much the same prototype as dhanuxp & I posted earlier?

                              btw, if you use the [code][/code] tags your code is much more readable.
                              I'm not anti-social, I just don't like people -Tommy Holden

                              Comment

                              Working...
                              X