/projects/jtopen-7.8/src/com/ibm/as400/access/JavaApplicationCall.java
Java | 1382 lines | 575 code | 137 blank | 670 comment | 82 complexity | defa30f3d1796bc87fa29815070dace6 MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // JTOpen (IBM Toolbox for Java - OSS version)
- //
- // Filename: JavaApplicationCall.java
- //
- // The source code contained herein is licensed under the IBM Public License
- // Version 1.0, which has been approved by the Open Source Initiative.
- // Copyright (C) 1997-2004 International Business Machines Corporation and
- // others. All rights reserved.
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- package com.ibm.as400.access;
-
- import java.beans.PropertyChangeListener;
- import java.beans.PropertyChangeSupport;
- import java.beans.PropertyVetoException;
- import java.beans.VetoableChangeListener;
- import java.beans.VetoableChangeSupport;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.io.InputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.Serializable;
- import java.util.Enumeration;
- import java.util.Properties;
- import java.util.StringTokenizer;
- import java.util.Vector;
-
- /**
- * <P>
- * Provides an easy way to run Java
- * applications on the IBM i system's Java Virtual Machine from a client.
- * The client Java program specifies the environment, the program to run,
- * and the program parameters. The program then runs on the IBM i system's
- * Java Virtual Machine. Text-based input/output is provided by
- * JavaApplicationCall. Input can be sent to the Java program which
- * will receive the input via standard input (<b><tt>stdin</tt></b>).
- * Standard output (<b><tt>stdout</tt></b>) and
- * standard error (<b><tt>stderr</tt></b>) text generated by the Java program are received
- * by JavaApplicationCall and made available to the calling program.
- * JavaApplicationCall does not support displaying the graphical user
- * interface of the IBM i system's Java program on the client. Other Java
- * facilities, such as remote AWT must be used to display graphical
- * interfaces on the client.
- *
- * <P>
- * Sockets are used to send stdin, stdout and stderr between
- * client and IBM i system. The port used can be set via setPort(). The
- * default port sequence is 2850, 2851 and 2852. If the port is in use,
- * this class searches for available ports if findPort is true.
- * stdin, stdout and stderr are <i>not</i> transported
- * across a secure connection even when the rest of the Toolbox
- * is using SSL.
- *
- * <P>
- * Note: The presence of a firewall, in either direction between the IBM i system
- * and the client, may prevent JavaApplicationCall from
- * opening the necessary additional ports (for stdin, stdout, and stderr).
- * The administrator may need to authenticate the application through
- * the firewall in <i>both</i> directions:
- * From client to IBM i system; and from IBM i system to client.
- *
- * <P>
- * For example, suppose the Java class <tt>HelloWorld</tt> resides in directory
- * <tt>/javatest</tt> on the system. The following calls this program and
- * receives program output written to stdout and stderr.
- *
- * <a name="ex"> </a>
- * <pre>
- * import com.ibm.as400.access.*;
- *
- * public class test implements Runnable
- * {
- * JavaApplicationCall jaCall;
- *
- * public static void main(String[] args)
- * {
- * test me = new test();
- * me.Main(args);
- * }
- *
- *
- * void Main(String[] args)
- * {
- *
- * try
- * {
- * // The IBM i system where the Java program to run, is located.
- * AS400 as400 = new AS400();
- *
- * // Construct a JavaApplicationCall object.
- * jaCall = new JavaApplicationCall(as400);
- *
- * // Set the name of the Java application to be run.
- * jaCall.setJavaApplication("HelloWorld");
- *
- * // Set the classpath environment variable used by the IBM i system's
- * // JVM so it can find the class to run.
- * jaCall.setClassPath("/javatest");
- *
- * // Start the thread that will receive stdout
- * Thread outputThread = new Thread(this);
- * outputThread.start();
- *
- * // Start the program. The call to run() will not return
- * // until the IBM i system Java program completes. If the Toolbox
- * // cannot start the Java program, false is returned with
- * // a list of AS400Message objects indicating why the program
- * // could not start.
- * if (jaCall.run() != true)
- * {
- * AS400Message[] messageList = jaCall.getMessageList();
- * for (int msg = 0; msg < messageList.length; msg++)
- * System.out.println(messageList[msg].toString());
- * }
- * }
- * catch (Exception e) { e.printStackTrace(); }
- *
- * System.exit(0);
- * }
- *
- * // This thread will get the output from the IBM i system Java program,
- * // and print it. Note the call to sleep().
- * // The getXxxString() methods return immediately even if there is no data.
- * public void run()
- * {
- * while (true)
- * {
- * String stdOut = jaCall.getStandardOutString();
- * if (stdOut != null)
- * System.out.println(stdOut);
- *
- * String stdErr = jaCall.getStandardErrorString();
- * if (stdErr != null)
- * System.out.println(stdErr);
- *
- * try { Thread.sleep(100); } catch (Exception e) {}
- * }
- * }
- * }
- *
- *
- * </pre>
- *
- **/
-
- public class JavaApplicationCall implements Serializable
- {
- static final long serialVersionUID = 4L;
-
- // The variables represent the default stdin, stdout, and stderr port.
- private static int DEFAULT_STANDARD_ERROR_PORT = 2852;
- private static int DEFAULT_STANDARD_IN_PORT = 2850;
- private static int DEFAULT_STANDARD_OUT_PORT = 2851;
- private static int PORT_SEARCH_TIMES = 1000;
-
- private AS400 as400_ = null;
- private CommandCall command_ = null;
- private AS400Message[] messageList_ = null;
-
- // lists of listeners and event catchers
- private transient PropertyChangeSupport propertyChange_ = new PropertyChangeSupport(this);
- private transient VetoableChangeSupport vetoableChange_ = new VetoableChangeSupport(this);
- private transient Vector completedListeners_ = new Vector();
-
- private transient JavaApplicationCallThread openSocketsThread_ = null;
-
- // The variables represent connections built in the subsidiary threads.
- private transient ServerSocket error_ = null;
- private transient ServerSocket read_ = null;
- private transient ServerSocket write_ = null;
-
- // The variables represent the properties of JavaApplicationCall.
- private String classPath_ = "";
- private int defaultPort_ = DEFAULT_STANDARD_IN_PORT;
- private boolean findPort_ = true;
- private int garbageCollectionInitialSize_ = 2048;
- private String garbageCollectionMaximumSize_ = "*NOMAX";
- private int garbageCollectionFrequency_ = 50;
- private int garbageCollectionPriority_ = 20;
- private String interpret_ = "*OPTIMIZE";
- private String jobname_ = "QJVACMDSRV"; // @F0A
- private String javaApplication_ = null;
- private String optimization_ = "10";
- private String[] options_ = {"*NONE"};
- private String[] parameters_ = {};
- private Properties properties_ = null;
- private String securityCheckLevel_ = "*WARN";
- private int standardErrorPort_ = DEFAULT_STANDARD_ERROR_PORT;
- private int standardInPort_ = DEFAULT_STANDARD_IN_PORT;
- private int standardOutPort_ = DEFAULT_STANDARD_OUT_PORT;
-
-
- /**
- * Constructs a JavaApplicationCall object.
- **/
- public JavaApplicationCall()
- {
- }
-
-
-
- /**
- * Constructs a JavaApplicationCall object. The Java program
- * is on an IBM i <i>system</i>.
- *
- * @param system The system on which contains the Java program.
- **/
- public JavaApplicationCall(AS400 system)
- {
- if (system == null)
- throw new NullPointerException("system");
-
- as400_ = system;
- }
-
-
-
- /**
- * Constructs a JavaApplicationCall object. The Java program is namee
- * <i>application</i> and runs on system <i>system</i>.
- *
- * @param system The system on which contains the Java program.
- * @param application The name of Java program.
- **/
- public JavaApplicationCall(AS400 system, String application)
- {
- this(system);
-
- if (application == null)
- throw new NullPointerException("application");
-
- javaApplication_ = application;
- }
-
-
-
- /**
- * Constructs a JavaApplicationCall object. The Java program is named
- * <i>application</i> and runs on system <i>system</i>. <i>
- * classPath</i> is passed to the system as the value of the
- * CLASSPATH environment variable.
- *
- * @param system The system on which contains the Java program.
- * @param application The name of Java program.
- * @param classPath The value of the environment variable CLASSPATH.
- **/
- public JavaApplicationCall(AS400 system, String application, String classPath)
- {
- this(system, application);
-
- if (classPath == null)
- throw new NullPointerException("classPath");
-
- this.classPath_ = classPath;
- }
-
-
-
- /**
- * Adds an ActionCompletedListener to be notified when the Java application ends.
- * The specified ActionCompletedListeners <b>actionCompleted</b> method will
- * be called each time an application runs.
- *
- * @see #removeActionCompletedListener
- * @param listener The ActionCompletedListener.
- */
- public void addActionCompletedListener(ActionCompletedListener listener)
- {
- if (listener != null)
- completedListeners_.addElement(listener);
- else
- throw new NullPointerException("addActionCompletedListener");
- }
-
-
-
- /**
- * Adds a listener to be notified when the value of any bound property
- * changes.
- *
- * @see #removePropertyChangeListener
- * @param listener The listener.
- **/
- public void addPropertyChangeListener(PropertyChangeListener listener )
- {
- if (listener != null)
- propertyChange_.addPropertyChangeListener(listener);
- else
- throw new NullPointerException("addPropertyChangeListener");
- }
-
-
-
- /**
- * Adds a listener to be notified when the value of any constrained
- * property changes.
- *
- * @see #removeVetoableChangeListener
- * @param listener The listener.
- **/
- public void addVetoableChangeListener(VetoableChangeListener listener )
- {
- if (listener != null)
- vetoableChange_.addVetoableChangeListener(listener);
- else
- throw new NullPointerException("addVetoableChangeListener");
- }
-
-
-
- /**
- * Returns the value of the CLASSPATH environment variable when running
- * the Java program. Use the forward slash to separate path elements
- * and a colon to separate the elements of CLASSPATH. For example,
- * /dir1:/dir1/dir2/myClasses.jar.
- * <p>Valid values are:
- * <UL>
- * <li>*ENVVAR No setting is sent from the client to the IBM i system so the
- * IBM i system's default value of CLASSPATH is used.
- * <li>string The value that is set before the program is run.
- * </UL>
- *
- * @return The value of CLASSPATH.
- **/
- public String getClassPath()
- {
- return classPath_;
- }
-
-
-
- /**
- Returns the CommandCall object that was used in the most recent invocation of {@link #run() run()}.
- @return The CommandCall object; null if run() has not been called.
- **/
- public CommandCall getCommandCall()
- {
- return command_;
- }
-
-
-
-
- /**
- * Returns the default port used to transfer stdin, stdout,
- * and stderr between the client and the IBM i system. Three
- * ports are used. The port returned by this method is used for
- * stdin; (port + 1) is used for stdout; and (port + 2)
- * is used for stderr. If not otherwise specified, the default port is 2850.
- *
- * @return The default port.
- **/
- public int getDefaultPort()
- {
- return defaultPort_;
- }
-
-
-
-
- /**
- Gets stdin, stdout and stderr port.
- Also creates serversockets for stdin, stdout and stderr.
- **/
- private void getFreePort()
- {
- read_ = null;
- write_ = null;
- error_ = null;
-
- if (!isFindPort())
- {
- standardInPort_ = defaultPort_;
- standardOutPort_ = defaultPort_ + 1;
- standardErrorPort_ = defaultPort_ + 2;
- try
- {
- read_ = new ServerSocket(standardInPort_);
- }
- catch (Exception e)
- {
- Trace.log(Trace.ERROR, e.toString(), e);
- }
- try
- {
- write_ = new ServerSocket(standardOutPort_);
- }
- catch (Exception e)
- {
- Trace.log(Trace.ERROR, e.toString(), e);
- }
- try
- {
- error_ = new ServerSocket(standardErrorPort_);
- }
- catch (Exception e)
- {
- Trace.log(Trace.ERROR, e.toString(), e);
- }
- }
- else
- {
- standardInPort_ = searchPort(defaultPort_ , DEFAULT_STANDARD_IN_PORT);
- standardOutPort_ = searchPort(standardInPort_+1, DEFAULT_STANDARD_OUT_PORT);
- standardErrorPort_ = searchPort(standardOutPort_+1, DEFAULT_STANDARD_ERROR_PORT);
- }
-
- if (read_ == null || write_ == null || error_ == null)
- {
- try
- {
- if (read_ != null) read_.close();
- read_ = null;
- }
- catch(Exception e){}
- try
- {
- if (write_ != null) write_.close();
- write_ = null;
- }
- catch(Exception e){}
- try
- {
- if (error_ != null) error_.close();
- error_ = null;
- }
- catch(Exception e){}
-
- String msg = "Setup of connection with IBM i system failed.";
- Trace.log(Trace.ERROR, msg);
- throw new RuntimeException(msg);
- }
- }
-
- /**
- * Returns the relative frequency that garbage collection runs. This
- * value applies only to OS/400 V4R2 and V4R3. It is
- * ignored in V4R4 and later versions.
- *
- * @return The relative frequency.
- **/
- public int getGarbageCollectionFrequency()
- {
- return garbageCollectionFrequency_;
- }
-
-
-
- /**
- * Returns the initial size, in kilobytes, of the garbage collection heap.
- * A large size can keep the garbage collector from starting when
- * the Java program is small, improving performance.
- *
- * <p>Possible values are:
- * <UL>
- * <li>2048 The default initial size is 2048 kilobytes.
- *
- * <li>heapSize The initial value of the garbage collection heap in
- * kilobytes. We recommend the initial heap size be
- * 2048 kilobytes (the default) or larger.
- * </UL>
- * @return The initial size of the garbage collection heap.
- **/
- public int getGarbageCollectionInitialSize()
- {
- return garbageCollectionInitialSize_;
- }
-
-
-
-
- /**
- * Returns the maximum size, in kilobytes, that the garbage
- * collection heap can grow to. This value is used to
- * prevent runaway programs from consuming all available
- * storage.
- *
- * <p>Possible values are:
- * <UL>
- * <li>*NOMAX The default maximum size is not specified by the user. The
- * maximum is determined by the system. The heap will grow until
- * all system resources are depleted. Then a synchronous garbage
- * collection is started to reclaim resources no longer in use.
- *
- * <li>heapSize The value in kilobytes that the garbage collection
- * heap can grow to.
- * </UL>
- * @return The maximum size that the garbage collection heap can grow to.
- **/
- public String getGarbageCollectionMaximumSize()
- {
- return garbageCollectionMaximumSize_;
- }
-
-
-
- /**
- * Returns the priority of the tasks running garbage collection. This
- * value applies only to OS/400 V4R2 and V4R3. It is
- * ignored in V4R4 and later versions.
- *
- * @return The priority of the tasks.
- **/
- public int getGarbageCollectionPriority()
- {
- return garbageCollectionPriority_;
- }
-
-
-
-
-
- /**
- * Returns whether all Java class files should be run interpretively.
- *
- * <p>Possible values are:
- * <UL>
- * <li>*OPTIMIZE Whether all Java classes are run interpretively depends on the
- * value of the optimize property. If optimize is
- * *INTERPRET, all Java classes will be run
- * interpretively. If any other value was specified for
- * optimize, only Java classes with Java programs created
- * using CRTJVAPGM command and specifying OPTIMIZE(*INTERPRET) will
- * be run interpretively.
- *
- * <li>*NO Only Java classes with Java programs created using CRTJVAPGM
- * command and specifying OPTIMIZE(*INTERPRET) will be run
- * interpretively. Java classes that need a Java program created
- * will be created with the optimization level specified in the
- * optimize property.
- *
- * <li>*YES All Java classes will be run interpretively regardless of the
- * OPTIMIZE value associated Java program. Java classes that need
- * a Java program created will use the optimization level specified
- * in the optimize property.
- * </UL>
- *
- * @return Whether all Java class files should be run interpretively.
- **/
- public String getInterpret()
- {
- return interpret_;
- }
-
-
-
- /**
- * Returns the name of Java application to be run.
- * If the Java application is not be set, null is returned.
- *
- * @return The name of Java application.
- **/
- public String getJavaApplication()
- {
- return javaApplication_;
- }
-
-
-
- /**
- * Returns the name that this job will run under.
- * The maximum length returned is 10 characters.
- *
- * <p>Possible values are:
- * <UL>
- * <li>QJVACMDSRV - The default job name.
- *
- * <li>*GEN - The job name will be generated from the class name.
- *
- * <li>string - Any generic string value.
- * </UL>
- *
- * @return The value of the job name.
- * @since i5/OS V5R3M0
- **/
- public String getJobName() // @F0A
- {
- return jobname_;
- }
-
-
-
- /**
- *Returns the list of IBM i system messages generated if the Java program
- *cannot be started. Before run() is called and if the Java program
- *can be started, an empty list is returned.
- *
- *@return The array of AS400Message objects.
- */
- public AS400Message[] getMessageList()
- {
- return messageList_;
- }
-
-
-
- /**
- * Returns the optimization level of IBM i system Java programs that
- * will be created if no Java program is associated with the Java
- * class.
- *
- * *INTERPRET means the resulting Java program interprets the
- * class byte codes when invoked. For other optimization levels, the
- * Java program contains machine instruction sequences that are run
- * when the Java program is invoked.
- *
- * *INTERPRET Java programs are smaller but run slower than
- * Java programs created with higher optimization levels. As you
- * increase the optimization level beyond 10, the Java program
- * performance generally improves, but the time required to create the
- * Java program increases, and debugging is more difficult.
- *
- * <p>Possible values are:
- * <UL>
- * <li>10 The Java program contains a compiled version of the class file
- * byte codes and has only minimal additional compiler
- * optimization. Variables can be displayed and modified while
- * debugging.
- *
- * <li>*INTERPRET The Java program created does not contain machine specific
- * instructions. It will be interpreted when the program is
- * started. Variables can be displayed and modified while
- * debugging.
- *
- * If the INTERPRET property has a value of *OPTIMIZE, all of the
- * classes that run will be run interpreted even if there is an
- * optimized Java program associated with the class.
- *
- * <li>20 The Java program contains a compiled version of the class file
- * byte codes and has some additional compiler optimization.
- * Variables can be displayed but not modified while debugging.
- *
- * <li>30 The Java program contains a compiled version of the class file
- * byte codes and has more compiler optimization than optimization
- * level 20. During a debug session, user variables cannot be
- * changed, but can be displayed. The presented values may not be
- * the current values of the variables.
- *
- * <li>40 The Java program contains a compiled version of the class file
- * byte codes and has more compiler optimization than optimization
- * level 30. All call and instruction tracing is disabled.
- * </UL>
- * @return The optimization level of the IBM i system Java application.
- **/
- public String getOptimization()
- {
- return optimization_;
- }
-
- /**
- * Returns a list of special options used when running the Java class.
- *
- * <p>The possible values are:
- * <UL>
- * <li>*NONE No special options are used when running the Java class.
- *
- * <li>*VERBOSE A message is displayed each time a class file is loaded.
- *
- * <li>*DEBUG Allows the system debugger to be used for this Java program.
- *
- * <li>*VERBOSEGC A message is displayed for each garbage collection sweep.
- *
- * <li>*NOCLASSGC Unused classes are not reclaimed when garbage collection is run.
- * </UL>
- *
- * @return The options used when running the Java class.
- **/
- public String[] getOptions()
- {
- return options_;
- }
-
-
- /**
- * Returns parameter values that are passed to the Java
- * application. A maximum of 200 parameter values can be passed.
- *
- * @return The parameters when running the Java application.
- **/
- public String[] getParameters()
- {
- return parameters_;
- }
-
- /**
- * Returns the properties set on the IBM i system's JVM before running
- * the Java program.
- *
- * @return The properties.
- **/
- public Properties getProperties()
- {
- return properties_;
- }
-
- /**
- * Returns the level of warnings given for directories in the
- * CLASSPATH that have public write authority. A directory in the
- * CLASSPATH that has public write authority is a security exposure
- * because it may contain a class file with the same name as the one
- * you want to run. Whichever class file is found first is run.
- *
- * <p>The possible values are:
- * <UL>
- * <li>*WARN Warning message is sent for each directory in the CLASSPATH
- * that has public write authority.
- *
- * <li>*SECURE A warning message is sent for each directory in the CLASSPATH
- * that has public write authority. If one or more warning
- * messages are sent, an escape message is sent and the Java
- * program is not run.
- *
- * <li>*IGNORE Ignore the fact that directories in the CLASSPATH may have
- * public write authority. No warnings messages are sent.
- * </UL>
- * @return The level of warnings given for directories in the
- * CLASSPATH that have public write authority.
- **/
- public String getSecurityCheckLevel()
- {
- return securityCheckLevel_;
- }
-
- /**
- * Returns the stderr port.
- * If not changed, the default port 2852 is returned.
- *
- * @return The stderr port.
- **/
- private int getStandardErrorPort()
- {
- return standardErrorPort_;
- }
-
- /**
- * Returns the next string written to stderr by the program
- * running on the system.
- *
- * @return the next stderr string from the system.
- **/
- public String getStandardErrorString()
- {
- if (openSocketsThread_ != null)
- return openSocketsThread_.getStandardErrorString();
- else
- return null;
- }
-
- /**
- * Returns the stdin port.
- * If not set, the default port 2850 is returned.
- *
- * @return The stdin port.
- **/
- private int getStandardInPort()
- {
- return standardInPort_;
- }
-
- /**
- * Returns the stdout port.
- * If not set, the default port 2851 is returned.
- *
- * @return The stdout port.
- **/
- private int getStandardOutPort()
- {
- return standardOutPort_;
- }
-
- /**
- * Returns the next string written to stdout by the application.
- *
- * @return the string written to stdout.
- **/
- public String getStandardOutString()
- {
- if (openSocketsThread_ != null)
- return openSocketsThread_.getStandardOutString();
- else
- return null;
- }
-
- /**
- Returns the system which contains the Java program.
-
- @return The system.
- **/
- public AS400 getSystem()
- {
- return as400_;
- }
-
- /**
- Indicates if this class should search for a free port.
-
- @return true if this class will search for a free port; false otherwise.
- The default value is <tt>true</tt>.
- **/
- public boolean isFindPort()
- {
- return findPort_;
- }
-
- /**
- Deserializes and initializes the transient data.
- **/
- private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
-
- propertyChange_ = new PropertyChangeSupport(this);
- vetoableChange_ = new VetoableChangeSupport(this);
- completedListeners_ = new Vector();
- openSocketsThread_ = null;
- read_ = null;
- write_ = null;
- error_ = null;
- }
-
- /**
- * Removes this ActionCompletedListener from the list of listeners.
- * If the ActionCompletedListener is not on the list, nothing is done.
- *
- * @see #addActionCompletedListener
- * @param listener The ActionCompletedListener.
- */
- public synchronized void removeActionCompletedListener(ActionCompletedListener listener)
- {
- if (listener != null)
- completedListeners_.removeElement(listener);
- else
- throw new NullPointerException("removeActionCompletedListener");
- }
-
- /**
- * Removes a property change listener from the list of listeners.
- *
- * @see #addPropertyChangeListener
- * @param listener The listener.
- **/
- public void removePropertyChangeListener(PropertyChangeListener listener )
- {
- if (listener != null)
- propertyChange_.removePropertyChangeListener(listener);
- else
- throw new NullPointerException("removePropertyChangeListener");
- }
-
- /**
- * Removes a vetoable change listener from the list of listeners.
- *
- * @see #addVetoableChangeListener
- * @param listener The listener.
- **/
- public void removeVetoableChangeListener(VetoableChangeListener listener )
- {
- if (listener != null)
- vetoableChange_.removeVetoableChangeListener(listener );
- else
- throw new NullPointerException("removeVetoableChangeListener");
- }
-
- /**
- Run the Java application. Control will not be returned to the
- calling application until the program completes. If the program
- does not start, a list of AS400Message object containing information
- about is failure is available.
-
- @return true if the program can be started, false otherwise.
-
- @exception AS400SecurityException If a security or authority error occurs.
- @exception ConnectionDroppedException If the connection is dropped unexpectedly.
- @exception ErrorCompletingRequestException If an error occurs before the request is completed.
- @exception InterruptedException If this thread is interrupted.
- @exception IOException If an error occurs while communicating with the system.
- @exception ServerStartupException If the host server cannot be started.
- @exception UnknownHostException If the system cannot be located.
-
- **/
- public boolean run() throws AS400SecurityException,
- ConnectionDroppedException,
- ErrorCompletingRequestException,
- InterruptedException,
- IOException,
- ServerStartupException,
- UnknownHostException
- {
- if (getSystem() == null)
- throw new ExtendedIllegalStateException("system",
- ExtendedIllegalStateException.PROPERTY_NOT_SET);
-
- if (getJavaApplication() == null)
- throw new ExtendedIllegalStateException("javaApplication",
- ExtendedIllegalStateException.PROPERTY_NOT_SET);
-
- // force signon so sign-on dialog up before
- // we create more threads.
- getSystem().getVRM(); // @D1A
-
- getFreePort();
- openSocketsThread_ = new JavaApplicationCallThread(read_, write_, error_);
- openSocketsThread_.start();
-
- command_ = new CommandCall(getSystem());
- command_.suggestThreadsafe(false); // JAVA cmd isn't threadsafe. @A1A
-
- // Construct commandstring
- // 1. CLASS
- // 2. PARM
- // 3. CLASSPATH
- // 4. CHKPATH
- // 5. OPTIMIZE
- // 6. INTERPRET
- // 7. PROP
- // 8. GCHINL
- // 9. GCHMAX
- // 10. GCFRQ
- // 11. GCPTY
- // 12. OPTION
-
- // 1.CLASS
- StringBuffer commandString = new StringBuffer("JAVA CLASS(" + getJavaApplication() + ") ");
- // 2.PARM
- String[] parm = getParameters();
- if (parm.length > 0)
- {
- commandString.append("PARM(");
- for (int i = 0 ; i < parm.length; i++) {
- commandString.append("'" + parm[i] + "' ");
- }
- // delete last space
- commandString.delete(commandString.length()-1, commandString.length());
- commandString.append(") ");
- }
- // 3.CLASSPATH
- if (getClassPath().length() > 0)
- commandString.append("CLASSPATH('" + getClassPath() + "') ");
- // 4.CHKPATH
- commandString.append("CHKPATH(" + getSecurityCheckLevel() +") ");
- // 5.OPTIMIZE
- commandString.append("OPTIMIZE(" + getOptimization() + ") ");
- // 6.INTERPRET
- commandString.append("INTERPRET(" + getInterpret() + ") ");
- // 7.PROP
-
- String localAddress = null; // @E1c
- // @E1a
- // Because of bugs in Java, cannot get the local // @E1a
- // address until a socket (not a server socket) // @E1a
- // is connected. // @E1a
- try // @E1a
- { // @E1a
- Socket pmSocket = new Socket(getSystem().getSystemName(), 449); // @E1a
- localAddress = pmSocket.getLocalAddress().getHostAddress(); // @E1a
- pmSocket.close(); // @E1a
- } // @E1a
- catch (Exception e) { localAddress = null; } // @E1a
- // @E1a
- // if new method didn't work, try the old technique. // @E1a
- if (localAddress == null) // @E1a
- {
- localAddress = "localhost";
-
- try
- {
- localAddress = java.net.InetAddress.getLocalHost().getHostAddress();
- }
- catch (java.net.UnknownHostException e)
- {
- Trace.log(Trace.ERROR , e.toString());
- }
- } // @E1a
-
- commandString.append("PROP("
- +"(os400.stdin 'port:"+localAddress+":"+new Integer(getStandardInPort()).toString()+"') "
- +"(os400.stdout 'port:"+localAddress+":"+new Integer(getStandardOutPort()).toString()+"') "
- +"(os400.stderr 'port:"+localAddress+":"+new Integer(getStandardErrorPort()).toString()+"') ");
- commandString.append("(os400.stdio.convert N)");
-
- if (getProperties() != null)
- {
- Enumeration e = properties_.keys();
- //add all other properties here
- while (e.hasMoreElements()) {
- String key = (String) e.nextElement();
- String value = (String)properties_.get(key);
- commandString.append(" (" + key + " " + value + ")");
- }
- }
-
- commandString.append(") ");
- // 8.GCHINL
- commandString.append("GCHINL(" + getGarbageCollectionInitialSize() + ") ");
- // 9.GCHMAX
- commandString.append("GCHMAX(" + getGarbageCollectionMaximumSize() + ") ");
- // 10.GCFRQ
- commandString.append("GCFRQ(" + getGarbageCollectionFrequency() + ") ");
- // 11.GCPTY
- commandString.append("GCPTY(" + getGarbageCollectionPriority() + ") ");
- // 12.OPTION
- String[] opt = getOptions();
- if (opt.length > 0)
- {
- commandString.append("OPTION(");
- for (int i = 0 ; i < opt.length; i++) {
- commandString.append(opt[i] + " ");
- }
- // delete last space
- commandString.delete(commandString.length()-1, commandString.length());
- commandString.append(") ");
- }
- // 13.JOB @F0A
- if (as400_.getVRM() >= 0x00050300) // New in V5R3M0 @F0A
- commandString.append("JOB(" + getJobName() +") "); // @F0A
- //run the command
- boolean success = false;
-
- // System.out.println(commandString);
-
- try
- {
- success = command_.run(commandString.toString());
- }
- catch (PropertyVetoException e) {}
- finally
- {
- openSocketsThread_.closeSockets();
- openSocketsThread_ = null;
- parameters_ = new String[0];
- properties_ = null;
- read_ = null;
- write_ = null;
- error_ = null;
- }
-
- if (success)
- {
- // fire ActionCompletedEvent
- Vector targets;
- targets = (Vector) completedListeners_.clone();
- ActionCompletedEvent actionEvt = new ActionCompletedEvent(this);
-
- for (int i = 0; i < targets.size(); i++)
- {
- ActionCompletedListener target = (ActionCompletedListener)targets.elementAt(i);
- target.actionCompleted(actionEvt);
- }
- }
-
- messageList_ = command_.getMessageList();
-
- return success;
- }
-
-
- /**
- Find a free port. If the port passed as a parameter is in use, try port+=3.
- If that is busy keep trying for up to 1000 times.
- If we cannot find a free port, return the original port.
- **/
- private int searchPort(int port, int whichPort)
- {
- ServerSocket test = null;
- int curport = port;
- boolean found = false;
- int times = 0;
-
- while (times <= PORT_SEARCH_TIMES)
- {
- try
- {
- test = new ServerSocket(curport);
- }
- catch (Exception e)
- {
- curport += 3;
- times++;
- continue;
- }
- found = true;
- break;
- }
- if (found)
- {
- if (whichPort == DEFAULT_STANDARD_IN_PORT)
- read_ = test;
- else if (whichPort == DEFAULT_STANDARD_OUT_PORT)
- write_ = test;
- else
- error_ = test;
- }
- else
- curport = port;
-
- return curport;
- }
-
- /**
- Sends the stdin to the application running on the system.
-
- @param data The stdin to the system.
- **/
- public void sendStandardInString(String data)
- {
- if (openSocketsThread_ != null)
- openSocketsThread_.sendStandardInString(data);
- }
-
- /** Sets the value of the CLASSPATH environment variable when running
- * the Java program. Use the forward slash to separate path elements
- * and a colon to separate the elements of CLASSPATH. For example,
- * /dir1:/dir1/dir2/myClasses.jar.
- * <p>Valid values are:
- * <UL>
- * <li>*ENVVAR No setting is sent from the client to the IBM i system so the
- * IBM i system's default value of CLASSPATH is used.
- * <li>string The value that is set before the program is run.
- * </UL>
- *
- * @param classPath The value of the classpath.
- * @exception PropertyVetoException If the change is vetoed.
- **/
- public void setClassPath(String classPath) throws PropertyVetoException
- {
- if (classPath != null)
- {
- String old = this.classPath_;
- vetoableChange_.fireVetoableChange("classPath",old,classPath);
- this.classPath_ = classPath;
- propertyChange_.firePropertyChange("classPath",old,classPath);
- }
- else
- throw new NullPointerException("classPath");
- }
-
- /**
- Sets the default port. This is the port for stdin.
- stdout is (port + 1) and stderr is (port + 2). {@link #setFindPort setFindPort()}
- can be used to tell this class to search for a free port if these
- ports are in use.
-
- @param port The default port.
- @exception PropertyVetoException If the change is vetoed.
- **/
- public void setDefaultPort(int port) throws PropertyVetoException
- {
- if (port > 0)
- {
- Integer old = new Integer(this.defaultPort_);
- vetoableChange_.fireVetoableChange("defaultPort", old, new Integer(port));
- this.defaultPort_ = port;
- propertyChange_.firePropertyChange("defaultPort", old, new Integer(port));
- }
- else
- throw new IllegalArgumentException("defaultPort");
- }
-
- /**
- Sets searching for a free port.
-
- @param search true to search for a port that is not in use; false to not search.
- The default value is <tt>true</tt>.
- @exception PropertyVetoException If the change is vetoed.
- **/
- public void setFindPort(boolean search) throws PropertyVetoException
- {
- Boolean old = new Boolean(findPort_);
- vetoableChange_.fireVetoableChange("findPort",old,new Boolean(search));
- findPort_ = search;
- propertyChange_.firePropertyChange("findPort",old,new Boolean(search));
- }
-
- /**
- Sets the relative frequency that garbage collection runs.
-
- This parameter is valid only for OS/400 V4R2 and V4R3 versions.
- It is ignored for V4R4 and later versions.
-
- @param frequency The relative frequency that garbage collection runs.
- @exception PropertyVetoException If the change is vetoed.
- **/
- public void setGarbageCollectionFrequency(int frequency) throws PropertyVetoException
- {
- if ((frequency >= 0) && (frequency <= 100))
- {
- int old = this.garbageCollectionFrequency_;
- vetoableChange_.fireVetoableChange("garbageCollectionFrequency",new Integer(old),new Integer(frequency));
- this.garbageCollectionFrequency_ = frequency;
- propertyChange_.firePropertyChange("garbageCollectionFrequency",new Integer(old),new Integer(frequency));
- }
- else
- throw new IllegalArgumentException("garbageCollectionFrequency");
- }
-
- /**
- Sets the initial size, in kilobytes, of the garbage collection
- heap. This is used to prevent garbage collection from starting on
- small programs.
-
- <p>The possible values are:
- <UL>
- <li>2048 The default initial size is 2048 kilobytes.
-
- <li>heap-initial-size The initial value of the garbage collection heap, in
- kilobytes. We recommend that the initial heap size be
- set to 2048 kilobytes (the default) or larger.
-
- </UL>
-
- @param size The initial size of the garbage collection heap.
- @exception PropertyVetoException If the change is vetoed.
- **/
-
- public void setGarbageCollectionInitialSize(int size) throws PropertyVetoException
- {
- if (size > 0)
- {
- if (Trace.traceOn_)
- {
- int sizeValue = -1;
- boolean nomax = false;
- try
- {
- sizeValue = Integer.parseInt(getGarbageCollectionMaximumSize());
- }
- catch(NumberFormatException e)
- {
- nomax = true;
- }
-
- if (!nomax && size > sizeValue)
- {
- Trace.log(Trace.WARNING , "Initial size ("+size+") exceeds specified maximum size (" + sizeValue + ")");
- }
- }
-
- int old = this.garbageCollectionInitialSize_;
- vetoableChange_.fireVetoableChange("garbageCollectionInitialSize",new Integer(old),new Integer(size));
- this.garbageCollectionInitialSize_ = size;
- propertyChange_.firePropertyChange("garbageCollectionInitialSize",new Integer(old),new Integer(size));
- }
- else
- throw new IllegalArgumentException("garbageCollectionInitialSize");
- }
-
- /**
- Sets the maximum size, in kilobytes, that the garbage
- collection heap can grow to. This is used to prevent runaway
- programs that consume all of the available storage. Normally,
- garbage collection runs as an asynchronous thread in parallel with
- other threads. If the maximum size is reached, all other threads
- are stopped while garbage collection takes place. This may
- adversely affect performance.
-
- <p>The possible values are:
- <UL>
- <li>*NOMAX The default maximum size is not specified by the user. The
- maximum is determined by the system. The heap will grow until
- all system resources are depleted. Then a synchronous garbage
- collection is started to reclaim resources no longer in use.
-
- <li>heap-maximum-size The value in kilobytes that the garbage collection
- heap can grow to.
- </UL>
-
- @param size The maximum size that the garbage collection heap can grow to.
- @exception PropertyVetoException If the change is vetoed.
- **/
- public void setGarbageCollectionMaximumSize(String size) throws PropertyVetoException
- {
- if (size != null)
- {
- if (!size.toUpperCase().equalsIgnoreCase("*NOMAX"))
- {
- try
- {
- Integer.parseInt(size);
- }
- catch(NumberFormatException e)
- {
- throw new IllegalArgumentException("garbageCollectionMaximumSize");
- }
- }
-
- String old = this.garbageCollectionMaximumSize_;
- vetoableChange_.fireVetoableChange("garbageCollectionMaximumSize",old,size);
- this.garbageCollectionMaximumSize_ = size;
- propertyChange_.firePropertyChange("garbageCollectionMaximumSize",old,size);
- }
- else
- throw new NullPointerException("garbageCollectionMaximumSize");
- }
-
- /**
- Sets the priority of the tasks running garbage collection.
- This parameter is valid only for OS/400 V4R3 and V4R2 versions.
- It is ignored for V4R4 and later versions.
-
- @param priority The priority of the tasks running garbage collection.
- @exception PropertyVetoException If the change is vetoed.
- **/
- public void setGarbageCollectionPriority(int priority) throws PropertyVetoException
- {
- if (priority == 10 || priority == 20 || priority == 30)
- {
- int old = this.garbageCollectionPriority_;
- vetoableChange_.fireVetoableChange("garbageCollectionPriority",new Integer(old),new Integer(priority));
- this.garbageCollectionPriority_ = priority;
- propertyChange_.firePropertyChange("garbageCollectionPriority",new Integer(old),new Integer(priority));
- }
- else
- throw new IllegalArgumentException("garbageCollectionPriority");
- }
-
-
-
-
-
- /**
- Sets whether all Java class files should be run interpretively.
-
- <p>The possible values are:
- <UL>
- <li>*OPTIMIZE Whether all Java classes are run interpretively depends on the
- value specified for the OPTIMIZE property. If
- *INTERPRET, all Java classes will be run
- interpretively. If any other value was specified for the
- OPTIMIZE property, only Java classes with Java programs created
- using CRTJVAPGM command and specifying OPTIMIZE(*INTERPRET) will
- be run interpretively.
-
- <li>*NO Only Java classes with Java programs created using CRTJVAPGM
- command and specifying OPTIMIZE(*INTERPRET) will be run
- interpretively. Java classes that need a Java program created
- will be created with the optimization level specified in the
- OPTIMIZE parameter.
-
- <li>*YES All Java classes will be run interpretively regardless of the
- OPTIMIZE value associated Java program. Java classes that need
- a Java program created will use the optimization level specified
- in the OPTIMIZE parameter.
-
- <li>*JIT All Java class files will be run using the just in time
- compiler (JIT) regardless of the OPTIMIZE value
- used when the associated Java program was created.
-
- @param interpret How all Java class files should be run interpretively.
- @exception PropertyVetoException If the change is vetoed.
- **/
- public void setInterpret(String interpret) throws PropertyVetoException
- {
- if (interpret != null)
- {
- if (interpret.equalsIgnoreCase("*OPTIMIZE") ||
- interpret.equalsIgnoreCase("*NO") ||
- interpret.equalsIgnoreCase("*YES") ||
- interpret.equalsIgnoreCase("*JIT")) // @D2a
- {
- String old = this.interpret_;
- vetoableChange_.fireVetoableChange("interpret",old,interpret);
- this.interpret_ = interpret;
- propertyChange_.firePropertyChange("interpret",old,interpret);
- }
- else
- throw new IllegalArgumentException("interpret");
- }
- else
- throw new NullPointerException("interpret");
- }
-
- /**
- Sets the Java application to be run.
-
- @param application The Java application to be run.
- @exception PropertyVetoException If the change is vetoed.
- **