Example #1
0
  public void onPrivateMessage(String sender, String login, String hostname, String msg) {
    String[] args = msg.split(" ");
    String cleancmd = args[0];
    String message = pmmsg(msg, commandprefix);

    for (Commands command : cmds) {
      if (message.startsWith(command.getCommandName())) {
        command.handleMessage(
            this, sender, sender, message.replace(command.getCommandName(), "").trim(), args);
      }
    }
  }
Example #2
0
  private void setEventRequests(VirtualMachine vm) {
    EventRequestManager erm = vm.eventRequestManager();

    // Normally, we want all uncaught exceptions.  We request them
    // via the same mechanism as Commands.commandCatchException()
    // so the user can ignore them later if they are not
    // interested.
    // FIXME: this works but generates spurious messages on stdout
    //        during startup:
    //          Set uncaught java.lang.Throwable
    //          Set deferred uncaught java.lang.Throwable
    Commands evaluator = new Commands();
    evaluator.commandCatchException(new StringTokenizer("uncaught java.lang.Throwable"));

    ThreadStartRequest tsr = erm.createThreadStartRequest();
    tsr.enable();
    ThreadDeathRequest tdr = erm.createThreadDeathRequest();
    tdr.enable();
  }
 public void sendObject(
     Object object,
     int primitiveTypeID,
     Commands.ValueObject valueObject,
     DataOutputStream out,
     boolean writeAsCommand,
     boolean flush)
     throws CommandException {
   int added = fillInValue(object, primitiveTypeID, valueObject);
   boolean sent = false;
   try {
     Commands.writeValue(
         out, valueObject, writeAsCommand, flush); // Write it back as a value command.
     sent = true;
   } finally {
     if (!sent) {
       // Ending due to some problem, so clean up any added objects from the id table.
       if ((added & OBJECT_ADDED) != 0) server.removeObject(valueObject.objectID);
       if ((added & CLASS_ADDED) != 0) server.removeObject(valueObject.classID);
     }
   }
 }
  /*
   * @param is
   * @param exp
   *
   * @since 1.1.0
   */
  private void sendExpressionProxyResolutions(
      Commands.ValueObject valueObject,
      final int[] proxyIDs,
      final ExpressionProcesserController exp)
      throws CommandException {
    class ExpressionProxyRetriever implements Commands.ValueRetrieve {
      int index = 0;
      Object[] proxyResolution = new Object[2];
      Commands.ValueObject worker = new Commands.ValueObject();

      public Commands.ValueObject nextValue() {
        int proxyID = proxyIDs[index++];
        if (exp.pullExpressionProxyValue(proxyID, proxyResolution)) {
          if (proxyResolution[1] != Void.TYPE) {
            if (((Class) proxyResolution[1]).isPrimitive()) {
              int returnTypeID = server.getIdentityID(proxyResolution[1]);
              // Need to tell worker the correct primitive type.
              fillInValue(proxyResolution[0], returnTypeID, worker);
            } else {
              fillInValue(proxyResolution[0], NOT_A_PRIMITIVE, worker);
            }
          } else
            worker.setFlag(
                ExpressionCommands
                    .EXPRESSIONPROXY_VOIDTYPE); // It was resolved, but to not set due to void type
                                                // of expression.
        } else
          worker.setFlag(ExpressionCommands.EXPRESSIONPROXY_NOTRESOLVED); // It wasn't resolved.

        return worker;
      }
    };

    valueObject.setArrayIDS(new ExpressionProxyRetriever(), proxyIDs.length, Commands.OBJECT_CLASS);
    Commands.writeValue(out, valueObject, true, false); // Write it back as a value command.
  }
Example #5
0
 public void onMessage(String channel, String sender, String login, String hostname, String msg) {
   String[] args = msg.split(" ");
   String cleancmd = args[0];
   String message = msg.replace(commandprefix, "").toLowerCase();
   if (cleancmd.startsWith("?help")) {
     StringBuilder cmdlist = new StringBuilder();
     for (Commands command : cmds) {
       cmdlist.append("?");
       cmdlist.append(command.getCommandName());
       cmdlist.append(", ");
     }
     this.sendMessage(channel, "Commands: " + cmdlist.toString());
   } else if (cleancmd.startsWith(commandprefix)) {
     for (Commands command : cmds) {
       if (cleancmd.startsWith(commandprefix + command.getCommandName())) {
         Files.savelog(this, channel, sender, msg);
         command.handleMessage(
             this, channel, sender, message.replace(command.getCommandName(), "").trim(), args);
       }
     }
   }
 }
Example #6
0
 public void run(String arg) {
   if (arg.equals("menus")) {
     updateMenus();
     return;
   }
   if (IJ.getApplet() != null) return;
   URL url = getClass().getResource("/ij/IJ.class");
   String ij_jar = url == null ? null : url.toString().replaceAll("%20", " ");
   if (ij_jar == null || !ij_jar.startsWith("jar:file:")) {
     error("Could not determine location of ij.jar");
     return;
   }
   int exclamation = ij_jar.indexOf('!');
   ij_jar = ij_jar.substring(9, exclamation);
   if (IJ.debugMode) IJ.log("Updater (jar loc): " + ij_jar);
   File file = new File(ij_jar);
   if (!file.exists()) {
     error("File not found: " + file.getPath());
     return;
   }
   if (!file.canWrite()) {
     String msg = "No write access: " + file.getPath();
     error(msg);
     return;
   }
   String[] list = openUrlAsList(IJ.URL + "/download/jars/list.txt");
   int count = list.length + 3;
   String[] versions = new String[count];
   String[] urls = new String[count];
   String uv = getUpgradeVersion();
   if (uv == null) return;
   versions[0] = "v" + uv;
   urls[0] = IJ.URL + "/upgrade/ij.jar";
   if (versions[0] == null) return;
   for (int i = 1; i < count - 2; i++) {
     String version = list[i - 1];
     versions[i] = version.substring(0, version.length() - 1); // remove letter
     urls[i] =
         IJ.URL + "/download/jars/ij" + version.substring(1, 2) + version.substring(3, 6) + ".jar";
   }
   versions[count - 2] = "daily build";
   urls[count - 2] = IJ.URL + "/ij.jar";
   versions[count - 1] = "previous";
   urls[count - 1] = IJ.URL + "/upgrade/ij2.jar";
   int choice = showDialog(versions);
   if (choice == -1 || !Commands.closeAll()) return;
   // System.out.println("choice: "+choice);
   // for (int i=0; i<urls.length; i++) System.out.println("  "+i+" "+urls[i]);
   byte[] jar = null;
   if ("daily build".equals(versions[choice]) && notes != null && notes.contains(" </title>"))
     jar = getJar("http://wsr.imagej.net/download/daily-build/ij.jar");
   if (jar == null) jar = getJar(urls[choice]);
   if (jar == null) {
     error("Unable to download ij.jar from " + urls[choice]);
     return;
   }
   Prefs.savePreferences();
   // System.out.println("saveJar: "+file);
   saveJar(file, jar);
   if (choice < count - 2) // force macro Function Finder to download fresh list
   new File(IJ.getDirectory("macros") + "functions.html").delete();
   System.exit(0);
 }
 public void sendException(Throwable e, Commands.ValueObject value, DataOutputStream out)
     throws CommandException {
   // Exception ocurred, return a value command with the exception within it.
   setExceptionIntoValue(e, value);
   Commands.sendErrorCommand(out, Commands.THROWABLE_SENT, value);
 }
 /*
  * @param exp
  * @param valueObject
  * @throws CommandException
  *
  * @since 1.1.0
  */
 private void sendNoValueErrorCommand(
     ExpressionProcesserController exp, Commands.ValueObject valueObject) throws CommandException {
   setExceptionIntoValue(exp.getErrorThrowable(), valueObject);
   Commands.sendErrorCommand(
       out, ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION, valueObject);
 }
  private void processExpressionCommand(
      Commands.ValueObject valueObject, InvokableValueSender valueSender)
      throws IOException, CommandException {
    Integer expressionID = new Integer(in.readInt());
    byte cmdType = in.readByte();
    ExpressionProcesserController exp = null;
    switch (cmdType) {
      case ExpressionCommands.START_EXPRESSION_TREE_PROCESSING:
        byte trace = in.readByte();
        if (trace == ExpressionCommands.TRACE_DEFAULT)
          exp = new ExpressionProcesserController(server, this);
        else
          exp =
              new ExpressionProcesserController(server, this, trace == ExpressionCommands.TRACE_ON);
        expressionProcessors.put(expressionID, exp);
        break;
      case ExpressionCommands.TRANSFER_EXPRESSION_REQUEST:
        exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
        sendObject(exp, NOT_A_PRIMITIVE, valueObject, out, true);
        break;
      case ExpressionCommands.RESUME_EXPRESSION_REQUEST:
        Commands.readValue(in, valueObject);
        exp = (ExpressionProcesserController) getInvokableObject(valueObject);
        expressionProcessors.put(expressionID, exp);
        break;
      case ExpressionCommands.PUSH_EXPRESSION:
        exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
        exp.process(in);
        break;
      case ExpressionCommands.SYNC_REQUEST:
        boolean haveProxies =
            in.readBoolean(); // See if we expression proxy ids that need to be resolved
        if (haveProxies) {
          Commands.readValue(in, valueObject);
          valueSender.initialize(valueObject);
          Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
        }

        exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
        if (haveProxies)
          sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
        if (exp.noErrors()) {
          valueObject.set(true); // Mark that all is good.
          Commands.writeValue(out, valueObject, true, true);
        } else {
          processExpressionError(exp, valueObject);
        }
        break;
      case ExpressionCommands.PULL_VALUE_REQUEST:
        haveProxies = in.readBoolean(); // See if we expression proxy ids that need to be resolved
        if (haveProxies) {
          Commands.readValue(in, valueObject);
          valueSender.initialize(valueObject);
          Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
        }

        exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
        if (haveProxies)
          sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
        if (exp.noErrors()) {
          try {
            Object[] pulledValue = exp.pullValue();
            // Send back the command code for pull value. Don't flush. We will flush when all done.
            if (((Class) pulledValue[1]).isPrimitive()) {
              int returnTypeID = server.getIdentityID(pulledValue[1]);
              // Need to tell sendObject the correct primitive type.
              sendObject(pulledValue[0], returnTypeID, valueObject, out, true, true);

            } else {
              sendObject(
                  pulledValue[0],
                  NOT_A_PRIMITIVE,
                  valueObject,
                  out,
                  true,
                  true); // Just send the object back. sendObject knows how to iterpret the type
            }
          } catch (NoExpressionValueException e) {
            sendNoValueErrorCommand(exp, valueObject);
          }
        } else processExpressionError(exp, valueObject);
        break;
      case ExpressionCommands.END_EXPRESSION_TREE_PROCESSING:
        exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
        exp.close();
        break;
    }
  }
  /**
   * Process and loop until told to stop. A callback_done will stop the loop and will return a
   * result. Otherwise null is returned.
   */
  public Object run() throws CommandException {
    Object result = null;
    boolean shutdown = false;
    boolean closeWhenDone = true;
    Commands.ValueObject valueObject =
        new Commands.ValueObject(); // Working value object so not continually recreated.
    InvokableValueSender valueSender =
        new InvokableValueSender(); // Working valuesender so not continually recreated.
    try {
      boolean doLoop = true;

      /**
       * Note: In the cases below you will see a lot of finally clauses that null variables out.
       * This is because this is a long running loop, and variables declared within blocks are not
       * garbage collected until the method is terminated, so these variables once set would never
       * be GC'd. The nulling at the end of the case makes sure that any of those objects set are
       * now available for garbage collection when necessary.
       */
      while (doLoop && isConnected()) {
        byte cmd = 0;
        try {
          if (LINUX_1_3) socket.setSoTimeout(1000); // Linux 1.3 bug, see comment on LINUX_1_3
          cmd = in.readByte();
          if (LINUX_1_3 && isConnected())
            socket.setSoTimeout(0); // Linux 1.3 bug, see comment on LINUX_1_3
        } catch (InterruptedIOException e) {
          continue; // Timeout, try again
        }
        switch (cmd) {
          case Commands.QUIT_CONNECTION:
            doLoop = false;
            break; // Close this connection

          case Commands.TERMINATE_SERVER:
            doLoop = false;
            shutdown = true; // Shutdown everything
            break;

          case Commands.GET_CLASS:
            String className = in.readUTF();
            Class aClass = null;
            Class superClass = null;
            String superClassName = null;
            boolean added = false;
            try {
              aClass =
                  Class.forName(
                      className); // Turns out using JNI format for array type will work fine.

              added = server.getIdentityID(aClass, valueObject);
              boolean isInterface = aClass.isInterface();
              boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
              superClass = aClass.getSuperclass();
              superClassName = (superClass != null) ? superClass.getName() : ""; // $NON-NLS-1$
              out.writeByte(Commands.GET_CLASS_RETURN);
              out.writeInt(valueObject.objectID);
              out.writeBoolean(isInterface);
              out.writeBoolean(isAbstract);
              out.writeUTF(superClassName);
              out.flush();
            } catch (ClassNotFoundException e) {
              valueObject.set();
              Commands.sendErrorCommand(out, Commands.GET_CLASS_NOT_FOUND, valueObject);
            } catch (ExceptionInInitializerError e) {
              sendException(e.getException(), valueObject, out);
            } catch (LinkageError e) {
              sendException(e, valueObject, out);
            } catch (Throwable e) {
              // Something bad, did we add a class? If we did remove it from the table.
              if (added) server.removeObject(server.getObject(valueObject.objectID));
              throw e;
            } finally {
              // clear out for GC to work.
              className = null;
              aClass = null;
              superClass = null;
              superClassName = null;
              valueObject.set();
            }
            break;

          case Commands.GET_CLASS_FROM_ID:
            int classID = in.readInt();
            try {
              aClass = (Class) server.getObject(classID);
              boolean isInterface = aClass.isInterface();
              boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
              superClass = aClass.getSuperclass();
              superClassName = (superClass != null) ? superClass.getName() : ""; // $NON-NLS-1$
              out.writeByte(Commands.GET_CLASS_ID_RETURN);
              out.writeUTF(aClass.getName());
              out.writeBoolean(isInterface);
              out.writeBoolean(isAbstract);
              out.writeUTF(superClassName);
              out.flush();
            } catch (ClassCastException e) {
              valueObject.set();
              Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
            } finally {
              // clear out for GC to work.
              aClass = null;
              superClass = null;
              superClassName = null;
              valueObject.set();
            }
            break;

          case Commands.GET_OBJECT_DATA:
            int objectID = in.readInt();
            Object anObject = null;
            try {
              anObject = server.getObject(objectID);
              valueObject.setObjectID(objectID, server.getIdentityID(anObject.getClass()));
              Commands.writeValue(out, valueObject, true);
            } catch (ClassCastException e) {
              valueObject.set();
              Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
            } finally {
              anObject = null; // Clear out for GC to work
              valueObject.set();
            }
            break;

          case Commands.RELEASE_OBJECT:
            int id = in.readInt();
            server.removeObject(server.getObject(id));
            break;

          case Commands.NEW_INIT_STRING:
            classID = in.readInt(); // ID Of class to do new upon.
            String initString = in.readUTF(); // The init string.
            Object newValue = null;
            Class theClass = null;
            try {
              theClass = (Class) server.getObject(classID);
              if (theClass == null) {
                // The class wasn't found. So imply ClassNotFound exception.
                throw new ClassNotFoundException();
              }

              InitializationStringParser parser = null;
              try {
                parser = InitializationStringParser.createParser(initString);
                newValue = parser.evaluate();
                boolean primitive = parser.isPrimitive();
                // If expected class is Void.TYPE, that means don't test the type of the result
                // to verify if correct type, just return what it really is.
                if (theClass != Void.TYPE && primitive != theClass.isPrimitive()) {
                  valueObject.set();
                  Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
                  continue; // Goto next command.
                }
                if (primitive) {
                  try {
                    // Need to do special tests for compatibility and assignment.
                    sendObject(
                        newValue,
                        classID != Commands.VOID_TYPE
                            ? classID
                            : server.getIdentityID(parser.getExpectedType()),
                        valueObject,
                        out,
                        true); // This will make sure it goes out as the correct primitive type
                  } catch (ClassCastException e) {
                    // The returned type is not of the correct type for what is expected.
                    valueObject.set();
                    Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
                    continue; // Goto next command
                  }
                } else {
                  if (newValue != null) {
                    // Test to see if they are compatible. (Null can be assigned to any object,
                    // so that is why it was tested out above).
                    // If expected class is Void.TYPE, that means don't test the type of the result
                    // to verify if correct type, just return what it really is.
                    if (theClass != Void.TYPE && !theClass.isInstance(newValue)) {
                      // The returned type is not of the correct type for what is expected.
                      valueObject.set();
                      Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
                      continue; // Goto next command
                    }
                  }
                  sendObject(
                      newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Send out as an object.
                }
              } catch (InitializationStringEvaluationException e) {
                if (e instanceof EvaluationException) {
                  // Want to return the real exception.
                  sendException(e.getOriginalException(), valueObject, out);
                } else {
                  // Couldn't be evaluated, return an error for this.
                  setExceptionIntoValue(e.getOriginalException(), valueObject);
                  Commands.sendErrorCommand(out, Commands.CANNOT_EVALUATE_STRING, valueObject);
                }
              } finally {
                parser = null; // Clear out for GC to work
              }
            } catch (Throwable e) {
              sendException(e, valueObject, out);
            } finally {
              // Clear out for GC to work
              initString = null;
              theClass = null;
              newValue = null;
              valueObject.set();
            }
            break;

          case Commands.INVOKE:
            Object target = null;
            Object[] parms = null;
            Class returnType = null;
            java.lang.reflect.Method aMethod = null;
            try {
              int methodID = in.readInt(); // ID of method to invoke
              aMethod = (java.lang.reflect.Method) server.getObject(methodID); // Method to invoke
              Commands.readValue(in, valueObject);
              target = getInvokableObject(valueObject);
              Commands.readValue(in, valueObject);
              if (valueObject.type == Commands.ARRAY_IDS) {
                // It is an array containing IDs, as it normally would be.
                valueSender.initialize(valueObject);
                Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                parms = (Object[]) valueSender.getArray();
              } else {
                // It is all objects or null, so it should be an Object[] or null. If not, then this
                // is an error.
                parms = (Object[]) valueObject.anObject;
              }

              if (!aMethod.isAccessible())
                aMethod.setAccessible(
                    true); // We will allow all to occur. Let access control be handled by IDE and
                           // compiler.
              newValue = aMethod.invoke(target, parms);
              returnType = aMethod.getReturnType();
              if (returnType.isPrimitive()) {
                int returnTypeID = server.getIdentityID(returnType);
                // Need to tell sendObject the correct primitive type.
                sendObject(newValue, returnTypeID, valueObject, out, true);

              } else {
                sendObject(
                    newValue,
                    NOT_A_PRIMITIVE,
                    valueObject,
                    out,
                    true); // Just send the object back. sendObject knows how to iterpret the type
              }
            } catch (CommandException e) {
              throw e; // Throw it again. These we don't want to come up as an exception proxy.
                       // These should end the thread.
            } catch (java.lang.reflect.InvocationTargetException e) {
              // This is a wrappered exception. Return the wrappered one so it looks like
              // it was the real one. (Sometimes the method being invoked is on a
              // java.lang.reflect.Constructor.newInstance,
              // which in turn is an InvocationTargetException, so we will go until we don't have an
              // InvocationTargetException.
              Throwable t = e;
              do {
                t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
              } while (t instanceof java.lang.reflect.InvocationTargetException);
              sendException(t, valueObject, out);
            } catch (Throwable e) {
              sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
            } finally {
              // Clear out for GC to work
              valueObject.set();
              parms = null;
              target = null;
              aMethod = null;
              returnType = null;
              newValue = null;
              valueSender.clear();
            }
            break;

          case Commands.INVOKE_WITH_METHOD_PASSED:
            aClass = null;
            String methodName = null;
            Class[] parmTypes = null;
            target = null;
            parms = null;
            returnType = null;
            aMethod = null;

            try {
              Commands.readValue(in, valueObject);
              aClass = (Class) getInvokableObject(valueObject); // The class that has the method.
              methodName = in.readUTF();
              Commands.readValue(in, valueObject);
              if (valueObject.type == Commands.ARRAY_IDS) {
                // It is an array containing IDs, as it normally would be.
                valueSender.initialize(valueObject);
                Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                parmTypes = (Class[]) valueSender.getArray();
              } else {
                // It null, so it should be an null. If not, then this is an error.
                parmTypes = null;
              }
              aMethod = aClass.getMethod(methodName, parmTypes);

              // Now we get the info for the invocation of the method and execute it.
              Commands.readValue(in, valueObject);
              target = getInvokableObject(valueObject);
              Commands.readValue(in, valueObject);
              if (valueObject.type == Commands.ARRAY_IDS) {
                // It is an array containing IDs, as it normally would be.
                valueSender.initialize(valueObject);
                Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                parms = (Object[]) valueSender.getArray();
              } else {
                // It is all objects or null, so it should be an Object[] or null. If not, then this
                // is an error.
                parms = (Object[]) valueObject.anObject;
              }

              if (!aMethod.isAccessible())
                aMethod.setAccessible(
                    true); // We will allow all to occur. Let access control be handled by IDE and
                           // compiler.
              newValue = aMethod.invoke(target, parms);
              returnType = aMethod.getReturnType();
              if (returnType.isPrimitive()) {
                int returnTypeID = server.getIdentityID(returnType);
                // Need to tell sendObject the correct primitive type.
                sendObject(newValue, returnTypeID, valueObject, out, true);

              } else {
                sendObject(
                    newValue,
                    NOT_A_PRIMITIVE,
                    valueObject,
                    out,
                    true); // Just send the object back. sendObject knows how to iterpret the type
              }
            } catch (CommandException e) {
              throw e; // Throw it again. These we don't want to come up as an exception proxy.
                       // These should end the thread.
            } catch (java.lang.reflect.InvocationTargetException e) {
              // This is a wrappered exception. Return the wrappered one so it looks like
              // it was the real one. (Sometimes the method being invoked is on a
              // java.lang.reflect.Constructor.newInstance,
              // which in turn is an InvocationTargetException, so we will go until we don't have an
              // InvocationTargetException.
              Throwable t = e;
              do {
                t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
              } while (t instanceof java.lang.reflect.InvocationTargetException);
              sendException(t, valueObject, out);

            } catch (Throwable e) {
              sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
            } finally {
              aClass = null;
              methodName = null;
              parmTypes = null;
              // Clear out for GC to work
              valueObject.set();
              parms = null;
              target = null;
              aMethod = null;
              returnType = null;
              newValue = null;
              valueSender.clear();
            }
            break;

          case Commands.GET_ARRAY_CONTENTS:
            try {
              target = server.getObject(in.readInt()); // Array to get the ids for.
              valueObject.setArrayIDS(
                  new ArrayContentsRetriever(target),
                  Array.getLength(target),
                  Commands.OBJECT_CLASS);
              Commands.writeValue(out, valueObject, true); // Write it back as a value command.
            } catch (CommandException e) {
              throw e; // Throw it again. These we don't want to come up as an exception proxy.
                       // These should end the thread.
            } catch (Throwable e) {
              sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
            } finally {
              target = null;
              valueObject.set();
            }
            break;

          case Commands.CALLBACK_DONE:
            try {
              if (connectionThread != null) {
                valueObject.set();
                Commands.sendErrorCommand(out, Commands.UNKNOWN_COMMAND_SENT, valueObject);
              } else {
                try {
                  Commands.readBackValue(in, valueObject, Commands.NO_TYPE_CHECK);
                  if (valueObject.type == Commands.ARRAY_IDS) {
                    // It is an array containing IDs, as it normally would be.
                    valueSender.initialize(valueObject);
                    Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                    result = valueSender.getArray();
                  } else {
                    result = getInvokableObject(valueObject);
                  }
                  doLoop = false; // We need to terminate and return result
                  closeWhenDone = false; // Don't close, we will continue.
                } catch (CommandErrorException e) {
                  // There was an command error on the other side. This means
                  // connection still good, but don't continue the callback processing.
                  doLoop = false; // We need to terminate and return result
                  closeWhenDone = false; // Don't close, we will continue.
                  throw e; // Let it go on out.
                }
              }
            } finally {
              valueObject.set();
              valueSender.clear();
            }
            break;

          case Commands.ERROR:
            try {
              // Got an error command. Don't know what to do but read the
              // value and simply print it out.
              Commands.readValue(in, valueObject);
              result = getInvokableObject(valueObject);
              System.out.println("Error sent to server: Result=" + result); // $NON-NLS-1$
            } finally {
              valueObject.set();
            }
            break;

          case Commands.EXPRESSION_TREE_COMMAND:
            try {
              processExpressionCommand(valueObject, valueSender);
            } finally {
              valueObject.set();
              valueSender.clear();
            }
            break;

          default:
            // Unknown command. We don't know how long it is, so we need to shut the connection
            // down.
            System.err.println("Error: Invalid cmd send to server: Cmd=" + cmd); // $NON-NLS-1$
            doLoop = false;
            closeWhenDone = true;
            break;
        }
      }
    } catch (EOFException e) {
      // This is ok. It means that the connection on the other side was terminated.
      // So just accept this and go down.
    } catch (CommandException e) {
      throw e;
    } catch (SocketException e) {
      if (socket != null)
        throw new UnexpectedExceptionCommandException(
            false, e); // socket null means a valid close request
    } catch (Throwable e) {
      e.printStackTrace();
    } finally {
      if (closeWhenDone) {
        try {
          for (Iterator itr = expressionProcessors.values().iterator(); itr.hasNext(); ) {
            ExpressionProcesserController exp = (ExpressionProcesserController) itr.next();
            exp.close();
          }
        } finally {
          expressionProcessors.clear();
        }

        if (in != null)
          try {
            in.close();
          } catch (Exception e) {
          }
        in = null;
        if (out != null)
          try {
            out.close();
          } catch (Exception e) {
          }
        out = null;
        close();
      }
    }

    if (closeWhenDone && connectionThread != null) server.removeConnectionThread(connectionThread);
    if (shutdown) server.requestShutdown();

    return result;
  }
Example #11
0
  public static void main(String argv[]) throws MissingResourceException {
    redirectOutMessage();

    String cmdLine = "";
    String javaArgs = "";
    int traceFlags = VirtualMachine.TRACE_NONE;
    boolean launchImmediately = false;
    String connectSpec = null;

    MessageOutput.textResources =
        ResourceBundle.getBundle(
            "com.sun.tools.example.debug.tty.TTYResources", Locale.getDefault());

    for (int i = 0; i < argv.length; i++) {
      String token = argv[i];
      if (token.equals("-dbgtrace")) {
        if ((i == argv.length - 1) || !Character.isDigit(argv[i + 1].charAt(0))) {
          traceFlags = VirtualMachine.TRACE_ALL;
        } else {
          String flagStr = "";
          try {
            flagStr = argv[++i];
            traceFlags = Integer.decode(flagStr).intValue();
          } catch (NumberFormatException nfe) {
            usageError("dbgtrace flag value must be an integer:", flagStr);
            return;
          }
        }
      } else if (token.equals("-X")) {
        usageError("Use java minus X to see");
        return;
      } else if (
      // Standard VM options passed on
      token.equals("-v")
          || token.startsWith("-v:")
          || // -v[:...]
          token.startsWith("-verbose")
          || // -verbose[:...]
          token.startsWith("-D")
          ||
          // -classpath handled below
          // NonStandard options passed on
          token.startsWith("-X")
          ||
          // Old-style options (These should remain in place as long as
          //  the standard VM accepts them)
          token.equals("-noasyncgc")
          || token.equals("-prof")
          || token.equals("-verify")
          || token.equals("-noverify")
          || token.equals("-verifyremote")
          || token.equals("-verbosegc")
          || token.startsWith("-ms")
          || token.startsWith("-mx")
          || token.startsWith("-ss")
          || token.startsWith("-oss")) {

        javaArgs = addArgument(javaArgs, token);
      } else if (token.equals("-tclassic")) {
        usageError("Classic VM no longer supported.");
        return;
      } else if (token.equals("-tclient")) {
        // -client must be the first one
        javaArgs = "-client " + javaArgs;
      } else if (token.equals("-tserver")) {
        // -server must be the first one
        javaArgs = "-server " + javaArgs;
      } else if (token.equals("-sourcepath")) {
        if (i == (argv.length - 1)) {
          usageError("No sourcepath specified.");
          return;
        }
        Env.setSourcePath(argv[++i]);
      } else if (token.equals("-classpath")) {
        if (i == (argv.length - 1)) {
          usageError("No classpath specified.");
          return;
        }
        javaArgs = addArgument(javaArgs, token);
        javaArgs = addArgument(javaArgs, argv[++i]);
      } else if (token.equals("-attach")) {
        if (connectSpec != null) {
          usageError("cannot redefine existing connection", token);
          return;
        }
        if (i == (argv.length - 1)) {
          usageError("No attach address specified.");
          return;
        }
        String address = argv[++i];

        /*
         * -attach is shorthand for one of the reference implementation's
         * attaching connectors. Use the shared memory attach if it's
         * available; otherwise, use sockets. Build a connect
         * specification string based on this decision.
         */
        if (supportsSharedMemory()) {
          connectSpec = "com.sun.jdi.SharedMemoryAttach:name=" + address;
        } else {
          String suboptions = addressToSocketArgs(address);
          connectSpec = "com.sun.jdi.SocketAttach:" + suboptions;
        }
      } else if (token.equals("-listen") || token.equals("-listenany")) {
        if (connectSpec != null) {
          usageError("cannot redefine existing connection", token);
          return;
        }
        String address = null;
        if (token.equals("-listen")) {
          if (i == (argv.length - 1)) {
            usageError("No attach address specified.");
            return;
          }
          address = argv[++i];
        }

        /*
         * -listen[any] is shorthand for one of the reference implementation's
         * listening connectors. Use the shared memory listen if it's
         * available; otherwise, use sockets. Build a connect
         * specification string based on this decision.
         */
        if (supportsSharedMemory()) {
          connectSpec = "com.sun.jdi.SharedMemoryListen:";
          if (address != null) {
            connectSpec += ("name=" + address);
          }
        } else {
          connectSpec = "com.sun.jdi.SocketListen:";
          if (address != null) {
            connectSpec += addressToSocketArgs(address);
          }
        }
      } else if (token.equals("-launch")) {
        launchImmediately = true;
      } else if (token.equals("-listconnectors")) {
        Commands evaluator = new Commands();
        evaluator.commandConnectors(Bootstrap.virtualMachineManager());
        return;
      } else if (token.equals("-connect")) {
        /*
         * -connect allows the user to pick the connector
         * used in bringing up the target VM. This allows
         * use of connectors other than those in the reference
         * implementation.
         */
        if (connectSpec != null) {
          usageError("cannot redefine existing connection", token);
          return;
        }
        if (i == (argv.length - 1)) {
          usageError("No connect specification.");
          return;
        }
        connectSpec = argv[++i];
      } else if (token.equals("-help")) {
        usage();
      } else if (token.equals("-version")) {
        Commands evaluator = new Commands();
        evaluator.commandVersion(progname, Bootstrap.virtualMachineManager());
        System.exit(0);
      } else if (token.startsWith("-")) {
        usageError("invalid option", token);
        return;
      } else {
        // Everything from here is part of the command line
        cmdLine = addArgument("", token);
        for (i++; i < argv.length; i++) {
          cmdLine = addArgument(cmdLine, argv[i]);
        }
        break;
      }
    }

    /*
     * Unless otherwise specified, set the default connect spec.
     */

    /*
     * Here are examples of jdb command lines and how the options
     * are interpreted as arguments to the program being debugged.
     * arg1       arg2
     * ----       ----
     * jdb hello a b       a          b
     * jdb hello "a b"     a b
     * jdb hello a,b       a,b
     * jdb hello a, b      a,         b
     * jdb hello "a, b"    a, b
     * jdb -connect "com.sun.jdi.CommandLineLaunch:main=hello  a,b"   illegal
     * jdb -connect  com.sun.jdi.CommandLineLaunch:main=hello "a,b"   illegal
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello "a,b"'  arg1 = a,b
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello "a b"'  arg1 = a b
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello  a b'   arg1 = a  arg2 = b
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello "a," b' arg1 = a, arg2 = b
     */
    if (connectSpec == null) {
      connectSpec = "com.sun.jdi.CommandLineLaunch:";
    } else if (!connectSpec.endsWith(",") && !connectSpec.endsWith(":")) {
      connectSpec += ","; // (Bug ID 4285874)
    }

    cmdLine = cmdLine.trim();
    javaArgs = javaArgs.trim();

    if (cmdLine.length() > 0) {
      if (!connectSpec.startsWith("com.sun.jdi.CommandLineLaunch:")) {
        usageError("Cannot specify command line with connector:", connectSpec);
        return;
      }
      connectSpec += "main=" + cmdLine + ",";
    }

    if (javaArgs.length() > 0) {
      if (!connectSpec.startsWith("com.sun.jdi.CommandLineLaunch:")) {
        usageError("Cannot specify target vm arguments with connector:", connectSpec);
        return;
      }
      connectSpec += "options=" + javaArgs + ",";
    }

    try {
      if (!connectSpec.endsWith(",")) {
        connectSpec += ","; // (Bug ID 4285874)
      }
      Env.init(connectSpec, launchImmediately, traceFlags);
      new ThreadDumper();
    } catch (Exception e) {
      MessageOutput.printException("Internal exception:", e);
    }
  }