Example #1
0
 static {
   // dead-lock prevention.
   //
   // creating a new proxy class is a classloading activity, so it can create a dead-lock situation
   // if thread A starts classloading via RemoteClassLoader.ladClass(),
   // then thread B use JarCacheSupport.prefetch and tries to create a proxy for JarLoader
   //    (which blocks as Proxy.getProxyClass waits for RemoteClassLoader.defineClass lock by
   // thread A)
   // then thread A tries to touch JarLoader proxy (which blocks on thread B)
   //
   // to avoid situations like this, create proxy classes that we need during the classloading
   jarLoaderProxy = RemoteInvocationHandler.getProxyClass(JarLoader.class);
 }
Example #2
0
  /**
   * Creates a new channel.
   *
   * @param name See {@link #Channel(String, ExecutorService, Mode, InputStream, OutputStream,
   *     OutputStream, boolean, ClassLoader)}
   * @param exec See {@link #Channel(String, ExecutorService, Mode, InputStream, OutputStream,
   *     OutputStream, boolean, ClassLoader)}
   * @param transport The transport that we run {@link Channel} on top of.
   * @param base See {@link #Channel(String, ExecutorService, Mode, InputStream, OutputStream,
   *     OutputStream, boolean, ClassLoader)}
   * @param restricted See {@link #Channel(String, ExecutorService, Mode, InputStream, OutputStream,
   *     OutputStream, boolean, ClassLoader)}
   * @since 2.13
   */
  public Channel(
      String name,
      ExecutorService exec,
      CommandTransport transport,
      boolean restricted,
      ClassLoader base)
      throws IOException {
    this.name = name;
    this.executor = new InterceptingExecutorService(exec);
    this.isRestricted = restricted;
    this.underlyingOutput = transport.getUnderlyingStream();

    if (base == null) base = getClass().getClassLoader();
    this.baseClassLoader = base;

    if (export(this, false) != 1)
      throw new AssertionError(); // export number 1 is reserved for the channel itself
    remoteChannel = RemoteInvocationHandler.wrap(this, 1, IChannel.class, true, false);

    this.remoteCapability = transport.getRemoteCapability();
    this.pipeWriter = new PipeWriter(createPipeWriterExecutor());

    this.transport = transport;

    transport.setup(
        this,
        new CommandReceiver() {
          public void handle(Command cmd) {
            lastHeard = System.currentTimeMillis();
            if (logger.isLoggable(Level.FINE)) logger.fine("Received " + cmd);
            try {
              cmd.execute(Channel.this);
            } catch (Throwable t) {
              logger.log(
                  Level.SEVERE,
                  "Failed to execute command " + cmd + " (channel " + Channel.this.name + ")",
                  t);
              logger.log(Level.SEVERE, "This command is created here", cmd.createdAt);
            }
          }

          public void terminate(IOException e) {
            Channel.this.terminate(e);
          }
        });
  }
Example #3
0
  /*package*/ Channel(ChannelBuilder settings, CommandTransport transport) throws IOException {
    this.name = settings.getName();
    this.executor = new InterceptingExecutorService(settings.getExecutors());
    this.isRestricted = settings.isRestricted();
    this.underlyingOutput = transport.getUnderlyingStream();
    this.jarCache = settings.getJarCache();

    this.baseClassLoader = settings.getBaseLoader();

    if (export(this, false) != 1)
      throw new AssertionError(); // export number 1 is reserved for the channel itself
    remoteChannel = RemoteInvocationHandler.wrap(this, 1, IChannel.class, true, false);

    this.remoteCapability = transport.getRemoteCapability();
    this.pipeWriter = new PipeWriter(createPipeWriterExecutor());

    this.transport = transport;

    this.jarLoader =
        new JarLoaderImpl(); // TODO: figure out a mechanism to allow the user to share this across
    // Channels
    setProperty(JarLoader.OURS, export(JarLoader.class, jarLoader, false));

    transport.setup(
        this,
        new CommandReceiver() {
          public void handle(Command cmd) {
            lastHeard = System.currentTimeMillis();
            if (logger.isLoggable(Level.FINE)) logger.fine("Received " + cmd);
            try {
              cmd.execute(Channel.this);
            } catch (Throwable t) {
              logger.log(
                  Level.SEVERE,
                  "Failed to execute command " + cmd + " (channel " + Channel.this.name + ")",
                  t);
              logger.log(Level.SEVERE, "This command is created here", cmd.createdAt);
            }
          }

          public void terminate(IOException e) {
            Channel.this.terminate(e);
          }
        });
  }
Example #4
0
  /**
   * @param userProxy If true, the returned proxy will be capable to handle classes defined in the
   *     user classloader as parameters and return values. Such proxy relies on {@link
   *     RemoteClassLoader} and related mechanism, so it's not usable for implementing lower-layer
   *     services that are used by {@link RemoteClassLoader}.
   *     <p>To create proxies for objects inside remoting, pass in false.
   */
  /*package*/ <T> T export(Class<T> type, T instance, boolean userProxy) {
    if (instance == null) return null;

    // every so often perform GC on the remote system so that
    // unused RemoteInvocationHandler get released, which triggers
    // unexport operation.
    if ((++gcCounter) % 10000 == 0)
      try {
        send(new GCCommand());
      } catch (IOException e) {
        // for compatibility reason we can't change the export method signature
        logger.log(Level.WARNING, "Unable to send GC command", e);
      }

    // either local side will auto-unexport, or the remote side will unexport when it's GC-ed
    boolean autoUnexportByCaller = exportedObjects.isRecording();
    final int id = export(instance, autoUnexportByCaller);
    return RemoteInvocationHandler.wrap(null, id, type, userProxy, autoUnexportByCaller);
  }
Example #5
0
 @SuppressWarnings("unchecked")
 private synchronized void checkReply()
 {
    if (mc.hasReply()) {
       Message m = mc.getReply();
       if (m instanceof Error)
          error = ((Error) m).getException();
       else if (m instanceof MethodReturn) {
          try {
             rval = (ReturnType) RemoteInvocationHandler.convertRV(m.getSig(), m.getParameters(), me, conn);
          } catch (DBusExecutionException DBEe) {
             error = DBEe;
          } catch (DBusException DBe) {
             if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(Debug.ERR, DBe);
             error = new DBusExecutionException(DBe.getMessage());
          }
       }
    }
 }