Managing connections in Java programs

It is important to be able to create, start, and end connections to your server. The following discussion explains concepts central to managing connections to your server and also offers some code examples.

To connect to an IBM® i server, your Java™ program must create an AS400 object. The AS400 object contains up to one socket connection for each IBM i server type. A service corresponds to a job on the server and is the interface to the data on the server.

Note: When you create Enterprise JavaBeans (EJB), comply with the EJB specification that does not allow threads during your connection. Although turning off IBM Toolbox for Java thread support may slow your application, it is required to comply with the EJB specification.

Every connection to each server has its own job on the system. A different server supports each of the following:

  • JDBC
  • Program call and command call
  • Integrated file system
  • Print
  • Data queue
  • Record-level access
Note:
  • The print classes use one socket connection per AS400 object if the application does not try to do two things that require the network print server at the same time.
  • A print class creates additional socket connections to the network print server if needed. The extra conversations are disconnected if they are not used for 5 minutes.

The Java program can control the number of connections to the system. To optimize communications performance, a Java program can create multiple AS400 objects for the same server as shown in Figure 1. This creates multiple socket connections to the system.

Figure 1: Java program creating multiple AS400 objects and socket connections for the same system

Java program creating multiple AS400 objects and socket connections for the same system

To conserve server resources, create only one AS400 object as shown in Figure 2. This approach reduces the number of connections, which reduces the amount of resource used on the server.

Figure 2: Java program creating a single AS400 object and socket connection for the same system

Java program creating a single AS400 object and socket connection for the same system

Note: Although creating more connections increases the amount of resource used on the server, creating more connections can have a benefit. Having more connections enables your Java program to process things in parallel, which can give better throughput (transactions-per-second) and speed up your application.

You can also choose to use a connection pool to manage connections as shown in Figure 3. This approach reduces the amount of time it takes to connect by reusing a connection previously established for the user.

Figure 3: Java program getting a connection from an AS400ConnectionPool to a server

Java program getting a connection from an AS400ConnectionPool to a server

The following examples show how to create and use AS400 objects:

Example 1: In the following example, two CommandCall objects are created that send commands to the same server. Because the CommandCall objects use the same AS400 object, only one connection to the server is created.

     // Create an AS400 object.
     AS400 sys = new AS400("mySystem.myCompany.com");
 
     // Create two command call objects that use
     // the same AS400 object.
     CommandCall cmd1 = new CommandCall(sys,"myCommand1");
     CommandCall cmd2 = new CommandCall(sys,"myCommand2");
 
     // Run the commands.  A connection is made when the
     // first command is run.  Since they use the same
     // AS400 object the second command object will use
     // the connection established by the first command.
     cmd1.run();
     cmd2.run();

Example 2: In the following example, two CommandCall objects are created that send commands to the same system. Because the CommandCall objects use different AS400 objects, two connections to the server are created.

     // Create two AS400 objects to the same server.
     AS400 sys1 = new AS400("mySystem.myCompany.com");
     AS400 sys2 = new AS400("mySystem.myCompany.com");
 
     // Create two command call objects.  They use
     // different AS400 objects.
     CommandCall cmd1 = new CommandCall(sys1,"myCommand1");
     CommandCall cmd2 = new CommandCall(sys2,"myCommand2");
 
     // Run the commands.  A connection is made when the
     // first command is run.  Since the second command
     // object uses a different AS400 object, a second
     // connection is made when the second command is run.
     cmd1.run();
     cmd2.run();

Example 3: In the following example, a CommandCall object and an IFSFileInputStream object are created using the same AS400 object. Because the CommandCall object and the IFSFileInput Stream object use different services on the server, two connections are created.

     // Create an AS400 object.
     AS400 newConn1 = new AS400("mySystem.myCompany.com");
 
     // Create a command call object.
     CommandCall cmd = new CommandCall(newConn1,"myCommand1");
 
     // Create the file object.  Creating it causes the
     // AS400 object to connect to the file service.
     IFSFileInputStream file = new IFSFileInputStream(newConn1,"/myfile");
 
     // Run the command.  A connection is made to the
     // command service when the command is run.
     cmd.run();

Example 4: In the following example, an AS400ConnectionPool is used to get an IBM i connection. This example (like Example 3 above) does not specify a service, so the connection to the command service is made when the command is run.

     // Create an AS400ConnectionPool.
     AS400ConnectionPool testPool1 = new AS400ConnectionPool();

     // Create a connection.
     AS400 newConn1 = testPool1.getConnection("myAS400", "myUserID", "myPassword");

     // Create a command call object that uses the AS400 object.
     CommandCall cmd = new CommandCall(newConn1,"myCommand1");

     // Run the command.  A connection is made to the
     // command service when the command is run.
     cmd.run();

     // Return connection to pool.
     testPool1.returnConnectionToPool(newConn1);

Example 5: The following example uses AS400ConnectionPool to connect to a particular service when requesting the connection from the pool. This eliminates the time required to connect to the service when the command is run (see Example 4 above). If the connection is returned to the pool, the next call to get a connection can return the same connection object. This means that no extra connection time is needed, either on creation or use.

     // Create an AS400ConnectionPool.
     AS400ConnectionPool testPool1 = new AS400ConnectionPool();

     // Create a connection to the AS400.COMMAND service. (Use the service number constants 
     // defined in the AS400 class (FILE, PRINT, COMMAND, DATAQUEUE, and so on.))
     AS400 newConn1 = testPool1.getConnection("myAS400", "myUserID", "myPassword", AS400.COMMAND);

     // Create a command call object that uses the AS400 object.
     CommandCall cmd = new CommandCall(newConn1,"myCommand1");

     // Run the command.  A connection has already been made
     // to the command service.
     cmd.run();

     // Return connection to pool.
     testPool1.returnConnectionToPool(newConn1);

     // Get another connection to command service.  In this case, it will return the same 
     // connection as above, meaning no extra connection time will be needed either now or
     // when the command service is used.
     AS400 newConn2 = testPool1.getConnection("myAS400", "myUserID", "myPassword", AS400.COMMAND);

Starting and ending connections

The Java program can control when a connection is started and ended. By default, a connection is started when information is needed from the server. You can control exactly when the connection is made by calling the connectService() method on the AS400 object to preconnect to the server.

Using an AS400ConnectionPool, you can create a connection preconnected to a service without calling the connectService() method, as in Example 5 above.

The following examples show Java programs connecting to and disconnecting from the system.

Example 1: This example shows how to preconnect to the system:

     // Create an AS400 object.
     AS400 system1 = new AS400("mySystem.myCompany.com");
 
     // Connect to the command service.  Do it now
     // instead of when data is first sent to the
     // command service.  This is optional since the
     // AS400 object will connect when necessary.
     system1.connectService(AS400.COMMAND);

Example 2: Once a connection is started, the Java program is responsible for disconnecting, which is done either implicitly by the AS400 object, or explicitly by the Java program. A Java program disconnects by calling the disconnectService() method on the AS400 object. To improve performance, the Java program must disconnect only when the program is finished with a service. If the Java program disconnects before it is finished with a service, the AS400 object reconnects, if it is possible to reconnect, when data is needed from the service.

Figure 4 shows how disconnecting the connection for the first integrated file system object connection ends only that single instance of the AS400 object connection, not all of the integrated file system object connections.

Figure 4: Single object using its own service for an instance of an AS400 object is disconnected

Single object using its own service for an instance of an AS400 object is disconnected

This example shows how the Java program disconnects a connection:

     // Create an AS400 object.
     AS400 system1 = new AS400("mySystem.myCompany.com");
 
     // ... use command call to send several commands
     // to the server.  Since connectService() was not
     // called, the AS400 object automatically
     // connects when the first command is run.
 
     // All done sending commands so disconnect the
     // connection.
     system1.disconnectService(AS400.COMMAND);

Example 3: Multiple objects that use the same service and share the same AS400 object share a connection. Disconnecting ends the connection for all objects that are using the same service for each instance of an AS400 object as is shown in Figure 5.

Figure 5: All objects using the same service for an instance of an AS400 object are disconnected

All objects using the same service for an instance of an AS400 object are disconnected

For example, two CommandCall objects use the same AS400 object. When disconnectService() is called, the connection is ended for both CommandCall objects. When the run() method for the second CommandCall object is called, the AS400 object must reconnect to the service:

     // Create an AS400 object.
     AS400 sys = new AS400("mySystem.myCompany.com");
 
     // Create two command call objects.
     CommandCall cmd1 = new CommandCall(sys,"myCommand1");
     CommandCall cmd2 = new CommandCall(sys,"myCommand2");
 
     // Run the first command
     cmd1.run();
 
     // Disconnect from the command service.
     sys.disconnectService(AS400.COMMAND);
 
     // Run the second command.  The AS400 object
     // must reconnect to the server.
     cmd2.run();
 
     // Disconnect from the command service.  This
     // is the correct place to disconnect.
     sys.disconnectService(AS400.COMMAND);

Example 4: Not all IBM Toolbox for Java classes automatically reconnect. Some method calls in the integrated file system classes do not reconnect because the file may have changed. While the file was disconnected, some other process may have deleted the file or changed its contents. In the following example, two file objects use the same AS400 object. When disconnectService() is called, the connection is ended for both file objects. The read() for the second IFSFileInputStream object fails because it no longer has a connection to the server.

     // Create an AS400 object.
     AS400 sys = new AS400("mySystem.myCompany.com");
 
     // Create two file objects.  A connection to the
     // server is created when the first object is
     // created.  The second object uses the connection
     // created by the first object.
     IFSFileInputStream file1 = new IFSFileInputStream(sys,"/file1");
     IFSFileInputStream file2 = new IFSFileInputStream(sys,"/file2");
 
     // Read from the first file, then close it.
     int i1 = file1.read();
     file1.close();
 
     // Disconnect from the file service.
     sys.disconnectService(AS400.FILE);
 
     // Attempt to read from the second file.  This
     // fails because the connection to the file service
     // no longer exists.  The program must either
     // disconnect later or have the second file use a
     // different AS400 object (which causes it to
     // have its own connection).
     int i2 = file2.read();
 
     // Close the second file.
     file2.close();
 
     // Disconnect from the file service.  This
     // is the correct place to disconnect.
     sys.disconnectService(AS400.FILE);