Solved

Java and PCML?

Posted on 2004-04-28
13
1,408 Views
Last Modified: 2007-12-19
Hi,

I'm using a Java program with a PCML file to pass and retrieve parameters from a RPG service program, successfully. However, some of the RPG code I'm calling returns a value to indicate whether the program ran successfully or not. I have coded for this in the PCML file program element:

<program name="xx" entrypoint="xx" path="/QSYS.lib/XX.lib/XXXX.srvpgm" returnvalue="integer"/>

and ensured that the returned value is a 4byte integer (as per the PCML spec).

The problem is I can't figure out how to access this value within my Java code.

Can anyone tell me how?

Cheers,
Steve
0
Comment
Question by:stevebeech
13 Comments
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Are you running this in some way with Runtime.exec? If so, i suspect that the value you're talking about may well be the return value of the process, which of course you can read from waitFor
0
 

Author Comment

by:stevebeech
Comment Utility
You've lost me.

Here's my code (in case it helps):

public class SystemName {

      /**  Constructor for the SystemName object */
      public SystemName() { }

      /**
       *  Description of the Method
       *
       *@param  argv  Description of the Parameter
       */
      public static void main(String argv[]) {

            // Create and instantiate an AS/400 Object
            System.out.println("Connecting to iSeries...");

            AS400 sys = new AS400("XXX001", "username", "password");

            // Create Data Objects
            ProgramCallDocument pcml;

            boolean rc = false;

            String name;
            // String for returned name value
            String msgId;
            // String for returned name value
            String msgText;
            // Strings for as400 messags/400

            try {

                  // Instantiate the Objects (assign the variables)
                  pcml = new ProgramCallDocument(sys, "CallProgramPcml");

                  pcml.setValue("GETSYSNAMJ.sysname", new String("xxxxxxxx"));
                  
                  // Call the Program
                  rc = pcml.callProgram("GETSYSNAMJ");

                  // If return code is false, get messages from the iSeries
                  if (rc == false) {
                        // Retrieve list of AS/400 messages
                        AS400Message[] msgs = pcml.getMessageList("GETSYSNAMJ");

                        // Loop through all messages and write them to standard output
                        for (int m = 0; m < msgs.length; m++) {
                              msgId = msgs[m].getID();
                              msgText = msgs[m].getText();
                              System.out.println("    " + msgId + " - " + msgText);
                        }
                        System.out.println("Call to GETSYSNAMJ failed. See messages listed above");
                        System.exit(0);
                  }
                  // Return code was true, call to GetSysNam succeeded - woo-hoo!
                  else {
                        // Process the returned Data
                        name = (String) pcml.getValue("GETSYSNAMJ.sysname");
                        System.out.print("Returned System Name: " + name);
                        System.exit(0);
                  }
            } catch (PcmlException e) {
                  System.out.println(e.getLocalizedMessage());
                  e.printStackTrace();
                  System.out.println("Call to GETSYSNAMJ failed");
                  System.exit(0);
            }
            // Disconnect from AS/400
            sys.disconnectAllServices();
      }
}

and my PCML file:

<pcml version="3.0">
      <program name="GETSYSNAMJ" entrypoint="GETSYSNAMJ" path="/QSYS.lib/XHAJN.lib/SRV_SYSNM2.srvpgm" returnvalue="integer">
        <data name="sysname" type="char" length="10" usage="inputoutput" init="XXXXXXX"/>
      </program>
</pcml>


It's the returnvalue that I want to get at, but it isn't passed as a parameter (like sysname is)

??
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Can you show your imports?
0
 

Author Comment

by:stevebeech
Comment Utility
import com.ibm.as400.data.ProgramCallDocument;
import com.ibm.as400.data.PcmlException;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Message;
import java.math.BigDecimal;
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
I'd need quite a while to get into this very unfamiliar API, but it looks like output data is being obtained here:

http://www-919.ibm.com/servers/eserver/iseries/developer/java/documents/pcml.html. Look at the first Java source file
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:stevebeech
Comment Utility
Yes, output data is being obtained, but not the returnvalue attribute. Its not used in either of these examples. This is a problem with legacy RPG code which uses a return value to determine if a procedure completed or not. I reckon that new code would avoid using a return value (when it knows its to be accessed from Java with PCML) so its a problem I'll have to work around for now (means not using PCML, so extra coding).

Do you mind if I leave this question open for a few days to see if anyone else comes up with an answer? (I don't think they will - I've crawled the web looking for references to the returnvalue attribute with little success) If nothing turns up, then the points are yours CEHJ.

Cheers,

Steve
0
 
LVL 23

Expert Comment

by:rama_krishna580
Comment Utility
try this code..

Example of retrieving a list of information
PCML source for calling QGYOLAUS
<pcml version="1.0">

<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
   
  <!-- Format AUTU0150 - Other formats are available -->
  <struct name="autu0150">
    <data name="name"         type="char" length="10" />
    <data name="userOrGroup"  type="char" length="1"  />
    <data name="groupMembers" type="char" length="1"  />
    <data name="description"  type="char" length="50" />
  </struct>
   
  <!-- List information structure (common for "Open List" type APIs) -->
  <struct name="listInfo">
    <data name="totalRcds"    type="int"  length="4" />
    <data name="rcdsReturned" type="int"  length="4" />
    <data name="rqsHandle"    type="byte" length="4" />
    <data name="rcdLength"    type="int"  length="4" />
    <data name="infoComplete" type="char" length="1" />
    <data name="dateCreated"  type="char" length="7" />
    <data name="timeCreated"  type="char" length="6" />
    <data name="listStatus"   type="char" length="1" />
    <data                     type="byte" length="1" />
    <data name="lengthOfInfo" type="int"  length="4" />
    <data name="firstRecord"  type="int"  length="4" />
    <data                     type="byte" length="40" />
  </struct>
       
  <!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
  <program name="qgyolaus" path="/QSYS.lib/QGY.lib/QGYOLAUS.pgm" parseorder="listInfo receiver">
    <data   name="receiver"       type="struct" struct="autu0150" usage="output"
              count="listInfo.rcdsReturned" outputsize="receiverLength" />
    <data   name="receiverLength" type="int"    length="4"  usage="input" init="16384" />
    <data   name="listInfo"       type="struct" struct="listInfo" usage="output" />
    <data   name="rcdsToReturn"   type="int"    length="4"  usage="input" init="264" />
    <data   name="format"         type="char"   length="10" usage="input" init="AUTU0150" />
    <data   name="selection"      type="char"   length="10" usage="input" init="*USER" />
    <data   name="member"         type="char"   length="10" usage="input" init="*NONE" />
    <data   name="errorCode"      type="int"    length="4"  usage="input" init="0" />

  </program>
   
  <!-- Program QGYGTLE returned additional "records" from the list
       created by QGYOLAUS. -->
  <program name="qgygtle" path="/QSYS.lib/QGY.lib/QGYGTLE.pgm" parseorder="listInfo receiver">
    <data   name="receiver"       type="struct" struct="autu0150" usage="output"
            count="listInfo.rcdsReturned" outputsize="receiverLength" />
    <data   name="receiverLength" type="int"    length="4" usage="input" init="16384" />
    <data   name="requestHandle"  type="byte"   length="4" usage="input" />
    <data   name="listInfo"       type="struct" struct="listInfo" usage="output" />
    <data   name="rcdsToReturn"   type="int"    length="4" usage="input" init="264" />
    <data   name="startingRcd"    type="int"    length="4" usage="input" />
    <data   name="errorCode"      type="int"    length="4" usage="input" init="0" />
  </program>
   
  <!-- Program QGYCLST closes the list, freeing resources on the AS/400 -->
  <program name="qgyclst" path="/QSYS.lib/QGY.lib/QGYCLST.pgm" >
    <data   name="requestHandle"  type="byte"   length="4" usage="input" />
    <data   name="errorCode"      type="int"    length="4" usage="input" init="0" />
  </program>
</pcml>

 
Java program source for calling QGYOLAUS
import com.ibm.as400.data.ProgramCallDocument;
import com.ibm.as400.data.PcmlException;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Message;

// Example program to call "Retrieve List of Authorized Users" (QGYOLAUS) API
public class qgyolaus
{
   
  public static void main(String[] argv)  
  {
    AS400 as400System;         // com.ibm.as400.access.AS400
    ProgramCallDocument pcml;  // com.ibm.as400.data.ProgramCallDocument
    boolean rc = false;        // Return code from ProgramCallDocument.callProgram()
    String msgId, msgText;     // Messages returned from AS/400
    Object value;              // Return value from ProgramCallDocument.getValue()
     
    int[] indices = new int[1]; // Indices for access array value
    int nbrRcds,                // Number of records returned from QGYOLAUS and QGYGTLE
        nbrUsers;               // Total number of users retrieved
    String listStatus;          // Status of list on AS/400
    byte[] requestHandle = new byte[4];

    System.setErr(System.out);
       
    // Construct AS400 without parameters, user will be prompted
    as400System = new AS400();
     
    try
    {
      // Uncomment the following to get debugging information
      //com.ibm.as400.data.PcmlMessageLog.setTraceEnabled(true);
     
      System.out.println("Beginning PCML Example..");
      System.out.println("    Constructing ProgramCallDocument for QGYOLAUS API...");
     
      // Construct ProgramCallDocument
      // First parameter is system to connect to
      // Second parameter is pcml resource name. In this example,
      // serialized PCML file "qgyolaus.pcml.ser" or
      // PCML source file "qgyolaus.pcml" must be found in the classpath.
      pcml = new ProgramCallDocument(as400System, "qgyolaus");
     
      // All input parameters have default values specified in the PCML source.
      // Do not need to set them using Java code.
     
      // Request to call the API
      // User will be prompted to sign on to the system
      System.out.println("    Calling QGYOLAUS API requesting information for the sign-on user.");
      rc = pcml.callProgram("qgyolaus");

      // If return code is false, we received messages from the AS/400
      if(rc == false)
      {
        // Retrieve list of AS/400 messages
        AS400Message[] msgs = pcml.getMessageList("qgyolaus");
       
        // Iterate through messages and write them to standard output
        for (int m = 0; m < msgs.length; m++)
        {
            msgId = msgs[m].getID();
            msgText = msgs[m].getText();
            System.out.println("    " + msgId + " - " + msgText);
        }
        System.out.println("** Call to QGYOLAUS failed. See messages above **");
        System.exit(0);
      }
      // Return code was true, call to QGYOLAUS succeeded
      // Write some of the results to standard output
      else
      {
        boolean doneProcessingList = false;
        String programName = "qgyolaus";
        nbrUsers = 0;
        while (!doneProcessingList)
        {
          nbrRcds = pcml.getIntValue(programName + ".listInfo.rcdsReturned");
          requestHandle = (byte[]) pcml.getValue(programName + ".listInfo.rqsHandle");
         
          // Iterate through list of users
          for (indices[0] = 0; indices[0] < nbrRcds; indices[0]++)
          {
               value = pcml.getValue(programName + ".receiver.name", indices);
               System.out.println("User:  " + value);
           
               value = pcml.getValue(programName + ".receiver.description", indices);
               System.out.println("\t\t" + value);    
          }
         
          nbrUsers += nbrRcds;
         
          // See if we retrieved all the users.
          // If not, subsequent calls to "Get List Entries" (QGYGTLE)
          // would need to be made to retrieve the remaining users in the list.
          listStatus = (String) pcml.getValue(programName + ".listInfo.listStatus");
          if ( listStatus.equals("2")   // List is marked as "Complete"
            || listStatus.equals("3") ) // Or list is marked "Error building"
          {
            doneProcessingList = true;
          }
          else
          {
            programName = "qgygtle";
           
            // Set input parameters for QGYGTLE
            pcml.setValue("qgygtle.requestHandle", requestHandle);
            pcml.setIntValue("qgygtle.startingRcd", nbrUsers + 1);
           
            // Call "Get List Entries" (QGYGTLE) to get more users from list
            rc = pcml.callProgram("qgygtle");
     
            // If return code is false, we received messages from the AS/400
            if(rc == false)
            {
              // Retrieve list of AS/400 messages
              AS400Message[] msgs = pcml.getMessageList("qgygtle");
             
              // Iterate through messages and write them to standard output
              for (int m = 0; m < msgs.length; m++)
              {
                  msgId = msgs[m].getID();
                  msgText = msgs[m].getText();
                  System.out.println("    " + msgId + " - " + msgText);
              }
              System.out.println("** Call to QGYGTLE failed. See messages above **");
              System.exit(0);
            }
            // Return code was true, call to QGYGTLE succeeded
           
          }
        }
        System.out.println("Number of users returned:  " + nbrUsers);
       
        // Call the "Close List" (QGYCLST) API
        pcml.setValue("qgyclst.requestHandle", requestHandle);
        rc = pcml.callProgram("qgyclst");
      }
    }
    catch(PcmlException e)
    {
      System.out.println(e.getLocalizedMessage());    
      e.printStackTrace();
      System.out.println("*** Call to QGYOLAUS failed. ***");
      System.exit(0);
    }

    System.exit(0);
  }
}

Example of retrieving a list of information
PCML source for calling QGYOLAUS
<pcml version="1.0">

<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
   
  <!-- Format AUTU0150 - Other formats are available -->
  <struct name="autu0150">
    <data name="name"         type="char" length="10" />
    <data name="userOrGroup"  type="char" length="1"  />
    <data name="groupMembers" type="char" length="1"  />
    <data name="description"  type="char" length="50" />
  </struct>
   
  <!-- List information structure (common for "Open List" type APIs) -->
  <struct name="listInfo">
    <data name="totalRcds"    type="int"  length="4" />
    <data name="rcdsReturned" type="int"  length="4" />
    <data name="rqsHandle"    type="byte" length="4" />
    <data name="rcdLength"    type="int"  length="4" />
    <data name="infoComplete" type="char" length="1" />
    <data name="dateCreated"  type="char" length="7" />
    <data name="timeCreated"  type="char" length="6" />
    <data name="listStatus"   type="char" length="1" />
    <data                     type="byte" length="1" />
    <data name="lengthOfInfo" type="int"  length="4" />
    <data name="firstRecord"  type="int"  length="4" />
    <data                     type="byte" length="40" />
  </struct>
       
  <!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
  <program name="qgyolaus" path="/QSYS.lib/QGY.lib/QGYOLAUS.pgm" parseorder="listInfo receiver">
    <data   name="receiver"       type="struct" struct="autu0150" usage="output"
              count="listInfo.rcdsReturned" outputsize="receiverLength" />
    <data   name="receiverLength" type="int"    length="4"  usage="input" init="16384" />
    <data   name="listInfo"       type="struct" struct="listInfo" usage="output" />
    <data   name="rcdsToReturn"   type="int"    length="4"  usage="input" init="264" />
    <data   name="format"         type="char"   length="10" usage="input" init="AUTU0150" />
    <data   name="selection"      type="char"   length="10" usage="input" init="*USER" />
    <data   name="member"         type="char"   length="10" usage="input" init="*NONE" />
    <data   name="errorCode"      type="int"    length="4"  usage="input" init="0" />

  </program>
   
  <!-- Program QGYGTLE returned additional "records" from the list
       created by QGYOLAUS. -->
  <program name="qgygtle" path="/QSYS.lib/QGY.lib/QGYGTLE.pgm" parseorder="listInfo receiver">
    <data   name="receiver"       type="struct" struct="autu0150" usage="output"
            count="listInfo.rcdsReturned" outputsize="receiverLength" />
    <data   name="receiverLength" type="int"    length="4" usage="input" init="16384" />
    <data   name="requestHandle"  type="byte"   length="4" usage="input" />
    <data   name="listInfo"       type="struct" struct="listInfo" usage="output" />
    <data   name="rcdsToReturn"   type="int"    length="4" usage="input" init="264" />
    <data   name="startingRcd"    type="int"    length="4" usage="input" />
    <data   name="errorCode"      type="int"    length="4" usage="input" init="0" />
  </program>
   
  <!-- Program QGYCLST closes the list, freeing resources on the AS/400 -->
  <program name="qgyclst" path="/QSYS.lib/QGY.lib/QGYCLST.pgm" >
    <data   name="requestHandle"  type="byte"   length="4" usage="input" />
    <data   name="errorCode"      type="int"    length="4" usage="input" init="0" />
  </program>
</pcml>

 
Java program source for calling QGYOLAUS
import com.ibm.as400.data.ProgramCallDocument;
import com.ibm.as400.data.PcmlException;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Message;

// Example program to call "Retrieve List of Authorized Users" (QGYOLAUS) API
public class qgyolaus
{
   
  public static void main(String[] argv)  
  {
    AS400 as400System;         // com.ibm.as400.access.AS400
    ProgramCallDocument pcml;  // com.ibm.as400.data.ProgramCallDocument
    boolean rc = false;        // Return code from ProgramCallDocument.callProgram()
    String msgId, msgText;     // Messages returned from AS/400
    Object value;              // Return value from ProgramCallDocument.getValue()
     
    int[] indices = new int[1]; // Indices for access array value
    int nbrRcds,                // Number of records returned from QGYOLAUS and QGYGTLE
        nbrUsers;               // Total number of users retrieved
    String listStatus;          // Status of list on AS/400
    byte[] requestHandle = new byte[4];

    System.setErr(System.out);
       
    // Construct AS400 without parameters, user will be prompted
    as400System = new AS400();
     
    try
    {
      // Uncomment the following to get debugging information
      //com.ibm.as400.data.PcmlMessageLog.setTraceEnabled(true);
     
      System.out.println("Beginning PCML Example..");
      System.out.println("    Constructing ProgramCallDocument for QGYOLAUS API...");
     
      // Construct ProgramCallDocument
      // First parameter is system to connect to
      // Second parameter is pcml resource name. In this example,
      // serialized PCML file "qgyolaus.pcml.ser" or
      // PCML source file "qgyolaus.pcml" must be found in the classpath.
      pcml = new ProgramCallDocument(as400System, "qgyolaus");
     
      // All input parameters have default values specified in the PCML source.
      // Do not need to set them using Java code.
     
      // Request to call the API
      // User will be prompted to sign on to the system
      System.out.println("    Calling QGYOLAUS API requesting information for the sign-on user.");
      rc = pcml.callProgram("qgyolaus");

      // If return code is false, we received messages from the AS/400
      if(rc == false)
      {
        // Retrieve list of AS/400 messages
        AS400Message[] msgs = pcml.getMessageList("qgyolaus");
       
        // Iterate through messages and write them to standard output
        for (int m = 0; m < msgs.length; m++)
        {
            msgId = msgs[m].getID();
            msgText = msgs[m].getText();
            System.out.println("    " + msgId + " - " + msgText);
        }
        System.out.println("** Call to QGYOLAUS failed. See messages above **");
        System.exit(0);
      }
      // Return code was true, call to QGYOLAUS succeeded
      // Write some of the results to standard output
      else
      {
        boolean doneProcessingList = false;
        String programName = "qgyolaus";
        nbrUsers = 0;
        while (!doneProcessingList)
        {
          nbrRcds = pcml.getIntValue(programName + ".listInfo.rcdsReturned");
          requestHandle = (byte[]) pcml.getValue(programName + ".listInfo.rqsHandle");
         
          // Iterate through list of users
          for (indices[0] = 0; indices[0] < nbrRcds; indices[0]++)
          {
               value = pcml.getValue(programName + ".receiver.name", indices);
               System.out.println("User:  " + value);
           
               value = pcml.getValue(programName + ".receiver.description", indices);
               System.out.println("\t\t" + value);    
          }
         
          nbrUsers += nbrRcds;
         
          // See if we retrieved all the users.
          // If not, subsequent calls to "Get List Entries" (QGYGTLE)
          // would need to be made to retrieve the remaining users in the list.
          listStatus = (String) pcml.getValue(programName + ".listInfo.listStatus");
          if ( listStatus.equals("2")   // List is marked as "Complete"
            || listStatus.equals("3") ) // Or list is marked "Error building"
          {
            doneProcessingList = true;
          }
          else
          {
            programName = "qgygtle";
           
            // Set input parameters for QGYGTLE
            pcml.setValue("qgygtle.requestHandle", requestHandle);
            pcml.setIntValue("qgygtle.startingRcd", nbrUsers + 1);
           
            // Call "Get List Entries" (QGYGTLE) to get more users from list
            rc = pcml.callProgram("qgygtle");
     
            // If return code is false, we received messages from the AS/400
            if(rc == false)
            {
              // Retrieve list of AS/400 messages
              AS400Message[] msgs = pcml.getMessageList("qgygtle");
             
              // Iterate through messages and write them to standard output
              for (int m = 0; m < msgs.length; m++)
              {
                  msgId = msgs[m].getID();
                  msgText = msgs[m].getText();
                  System.out.println("    " + msgId + " - " + msgText);
              }
              System.out.println("** Call to QGYGTLE failed. See messages above **");
              System.exit(0);
            }
            // Return code was true, call to QGYGTLE succeeded
           
          }
        }
        System.out.println("Number of users returned:  " + nbrUsers);
       
        // Call the "Close List" (QGYCLST) API
        pcml.setValue("qgyclst.requestHandle", requestHandle);
        rc = pcml.callProgram("qgyclst");
      }
    }
    catch(PcmlException e)
    {
      System.out.println(e.getLocalizedMessage());    
      e.printStackTrace();
      System.out.println("*** Call to QGYOLAUS failed. ***");
      System.exit(0);
    }

    System.exit(0);
  }
}

http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/rzahh/page1.htm

best of luck..
R.K
 
0
 

Author Comment

by:stevebeech
Comment Utility
I would, but it doesn't address my problem.

Let me clarify - I can get the PCML and Java working, in order to pass and retrieve parameters - that isn't the problem.

The problem is with the returnvalue attribute in the program element:

<program name="GETSYSNAMJ" entrypoint="GETSYSNAMJ" path="/QSYS.lib/XHAJN.lib/SRV_SYSNM2.srvpgm" returnvalue="integer">

i.e. returnvalue="integer"

This is the value I'd like to get hold of. Unfortunately it doesn't appear to be available (as its never assigned a name).

I know that its being passed back though, because I get an AS400 error if its not in the form of a PackedDecimal (in RPG) AND if I've specified it within the PCML file.

Steve.

0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>Do you mind if I leave this question open for a few days ...

No of course not. What i'd look for is the abstraction in the api that encapsulates the actual machine process. You should be able to get the process return value from this.
0
 

Author Comment

by:stevebeech
Comment Utility
Well, I found the solution!!!

The ProgramCallDocument class (which is the class used to call the PCML-specified program) has a method named getIntReturnValue(String name), and the name to be specified as a parameter is the name of the program element in the PCML document (in my case GETSYSNAMJ).

So adding the method:

int x  = pcml.getIntReturnValue("GETSYSNAMJ");

copies the returnvalue into x.

Phew.

Thanks all for your help.

Cheers,

Steve
0
 

Accepted Solution

by:
modulo earned 0 total points
Comment Utility
Closed, 100 points refunded.

modulo
Community Support Moderator
Experts Exchange
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Unable to open debugger port in Intellij idea 6 78
noX challenge 17 75
network + 7 73
json format text only 4 65
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now