, , , - , . , . , , , , .
package org.valhalla.classloader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class RemoteClassLoader extends ClassLoader {
private Socket socket;
private DataOutputStream dos;
private DataInputStream dis;
public RemoteClassLoader(Socket socket, ClassLoader parent) {
super(parent);
this.socket = socket;
OutputStream os;
InputStream is;
try {
os = socket.getOutputStream();
is = socket.getInputStream();
} catch (IOException e) {
throw new RuntimeException("Unable to get Socket output stream", e);
}
dos = new DataOutputStream(os);
dis = new DataInputStream(is);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> clz = null;
System.out.println("Looking up class: " + name);
synchronized(this.getClassLoadingLock(name)) {
try {
System.out.println("Sending request for class: " + name);
dos.writeUTF(name);
boolean success = dis.readBoolean();
System.out.println("Action was " + success);
if (success) {
System.out.println("Reading size of class file");
int len = dis.readInt();
System.out.println("Size of class is " + len);
byte data[] = new byte[len];
int cur, size = 0;
for (cur = 0 ; cur < len ; cur += size) {
size = dis.read(data, cur, len - cur);
System.out.println("Read size: " + size);
}
System.out.println("Completed reading class file for class " + name);
return defineClass(name, data, 0, len);
}
} catch (IOException e) {
throw new ClassNotFoundException("Class: " + name + " was not found", e);
}
}
return clz;
}
public void close() {
try {
if (socket != null && socket.isClosed() == false) {
this.socket.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
. , , , , .
, . , .
package org.valhalla.client;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class ClientConnection {
private Socket socket;
public ClientConnection(Socket socket) {
this.socket = socket;
}
public void process() {
try {
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
String name = null;
while ((name = dis.readUTF()) != null && name.length() > 0) {
System.out.println("Looking up class: " + name);
InputStream resource = ClassLoader.getSystemResourceAsStream(name.replace('.', '/') + ".class");
if (resource == null) {
System.out.println("Class not found: " + name);
dos.writeBoolean(false);
continue;
}
System.out.println("Found class: " + name);
try {
byte buf[] = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int size = 0;
while ((size = resource.read(buf)) > 0) {
bos.write(buf, 0, size);
}
byte clz[] = bos.toByteArray();
dos.writeBoolean(true);
System.out.println("Sendding class size: " + clz.length);
dos.writeInt(clz.length);
System.out.println("Sending class bytes");
dos.write(clz);
System.out.println("Sent class bytes");
} catch (Throwable t) {
t.printStackTrace();
dos.writeBoolean(false);
}
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
if (socket != null && socket.isClosed() == false) {
try { socket.close(); } catch(Throwable t) {}
}
}
}
}
, , , . , , .
package org.valhalla.classloader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class RemoteClassLoaderServer {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("syntax error: missing port");
System.exit(1);
}
int port = 0;
try {
port = Integer.parseInt(args[0]);
} catch(NumberFormatException nfe) {
System.out.println("Invalid port number: " + args[1]);
System.exit(2);
}
if (port < 0) {
System.out.println("Port cannot be negative: " + port);
}
ServerSocket server = null;
try {
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Unable to create server socket for port: " + port);
System.exit(3);
}
Socket s = null;
try {
s = server.accept();
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream(is);
System.out.println("Waiting for class name");
String name = dis.readUTF();
System.out.println("Received class name: " + name);
RemoteClassLoader rcl = new RemoteClassLoader(s, RemoteClassLoaderServer.class.getClassLoader());
System.out.println("Finding class: " + name);
Class<?> clz = rcl.loadClass(name);
Method m = clz.getMethod("main", String[].class);
System.out.println("Executing main method");
m.invoke(null, new Object[] { new String[0] });
System.out.println("done");
new DataOutputStream(s.getOutputStream()).writeUTF("");
} catch (Throwable e) {
e.printStackTrace();
} finally {
if (s != null && s.isClosed() == false) {
try { s.close(); } catch(Throwable t) {}
}
}
}
}
package org.valhalla.client;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientMain {
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
try {
Socket socket = new Socket("localhost", port);
System.out.println("Opened socket at port: " + port);
String name = Main.class.getName();
new DataOutputStream(socket.getOutputStream()).writeUTF(name);
System.out.println("Sent Class name: " + name);
ClientConnection conn = new ClientConnection(socket);
conn.process();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
.
org.valhalla.client;
public class Main {
public static void main(String args[]) {
Client client = new Client();
client.execute();
}
}
.
org.valhalla.client;
public class Client {
public void execute() {
System.out.println("######### We are calling the Client class execute method #####");
}
}
, .