private void call(ClassLoader loader, Object object) throws Exception {
        synchronized (lock) {
            parsing = true;
            since = System.currentTimeMillis();
        }
        try {
            Method method = getMethod(object, input.readUTF());
            Object[] args = new Object[method.getParameterTypes().length];
            for (int i = 0; i < args.length; i++) {
                args[i] = readObject(loader);
            }
            try {
                method.invoke(object, args);
                output.write(DONE);
            } catch (InvocationTargetException e) {
                output.write(ERROR);
                // Try to send the underlying Exception itself
                Throwable toSend = e.getCause();
                try {
                    ForkObjectInputStream.sendObject(toSend, output);
                } catch (NotSerializableException nse) {
                    // Need to build a serializable version of it
                    TikaException te = new TikaException(toSend.getMessage());
                    te.setStackTrace(toSend.getStackTrace());
                    ForkObjectInputStream.sendObject(te, output);
                }

            }
        } finally {
            synchronized (lock) {
                parsing = false;
                since = System.currentTimeMillis();
            }
        }
    }
Starts a forked server process using the standard input and output
streams for communication with the parent process. Any attempts by
stray code to read from standard input or write to standard output
is redirected to avoid interfering with the communication channel.

@param args command line arguments, ignored
@throws Exception if the server could not be started
tika-core/src/main/java/org/apache/tika/fork/ForkServer.java