*/ | */ | ||||
public byte[] toBytecode() throws IOException, CannotCompileException { | public byte[] toBytecode() throws IOException, CannotCompileException { | ||||
ByteArrayOutputStream barray = new ByteArrayOutputStream(); | ByteArrayOutputStream barray = new ByteArrayOutputStream(); | ||||
DataOutputStream out = new DataOutputStream(barray); | |||||
try { | |||||
try (DataOutputStream out = new DataOutputStream(barray)) { | |||||
toBytecode(out); | toBytecode(out); | ||||
} | } | ||||
finally { | |||||
out.close(); | |||||
} | |||||
return barray.toByteArray(); | return barray.toByteArray(); | ||||
} | } | ||||
public void writeFile(String directoryName) | public void writeFile(String directoryName) | ||||
throws CannotCompileException, IOException | throws CannotCompileException, IOException | ||||
{ | { | ||||
DataOutputStream out = makeFileOutput(directoryName); | |||||
try { | |||||
try (DataOutputStream out = makeFileOutput(directoryName)) { | |||||
toBytecode(out); | toBytecode(out); | ||||
} | } | ||||
finally { | |||||
out.close(); | |||||
} | |||||
} | } | ||||
protected DataOutputStream makeFileOutput(String directoryName) { | protected DataOutputStream makeFileOutput(String directoryName) { |
private void dumpClassFile(ClassFile cf) throws IOException | private void dumpClassFile(ClassFile cf) throws IOException | ||||
{ | { | ||||
DataOutputStream dump = makeFileOutput(debugDump); | |||||
try { | |||||
try (DataOutputStream dump = makeFileOutput(debugDump)) { | |||||
cf.write(dump); | cf.write(dump); | ||||
} | } | ||||
finally { | |||||
dump.close(); | |||||
} | |||||
} | } | ||||
/* See also checkModified() | /* See also checkModified() |
public URL find(String classname) { | public URL find(String classname) { | ||||
try { | try { | ||||
URLConnection con = openClassfile0(classname); | URLConnection con = openClassfile0(classname); | ||||
InputStream is = con.getInputStream(); | |||||
if (is != null) { | |||||
is.close(); | |||||
return con.getURL(); | |||||
try (InputStream is = con.getInputStream()) { | |||||
if (is != null) { | |||||
return con.getURL(); | |||||
} | |||||
} | } | ||||
} | } | ||||
catch (IOException e) {} | catch (IOException e) {} | ||||
URLConnection con = fetchClass0(host, port, | URLConnection con = fetchClass0(host, port, | ||||
directory + classname.replace('.', '/') + ".class"); | directory + classname.replace('.', '/') + ".class"); | ||||
int size = con.getContentLength(); | int size = con.getContentLength(); | ||||
InputStream s = con.getInputStream(); | |||||
try { | |||||
if (size <= 0) | |||||
try (InputStream s = con.getInputStream()) { | |||||
if (size <= 0) { | |||||
b = ClassPoolTail.readStream(s); | b = ClassPoolTail.readStream(s); | ||||
else { | |||||
} else { | |||||
b = new byte[size]; | b = new byte[size]; | ||||
int len = 0; | int len = 0; | ||||
do { | do { | ||||
int n = s.read(b, len, size - len); | int n = s.read(b, len, size - len); | ||||
if (n < 0) | |||||
if (n < 0) { | |||||
throw new IOException("the stream was closed: " | throw new IOException("the stream was closed: " | ||||
+ classname); | |||||
+ classname); | |||||
} | |||||
len += n; | len += n; | ||||
} while (len < size); | } while (len < size); | ||||
} | } | ||||
} | } | ||||
finally { | |||||
s.close(); | |||||
} | |||||
return b; | return b; | ||||
} | } |
} | } | ||||
private void processRMI(InputStream ins, OutputStream outs) | private void processRMI(InputStream ins, OutputStream outs) | ||||
throws IOException | |||||
{ | |||||
ObjectInputStream in = new ObjectInputStream(ins); | |||||
int objectId = in.readInt(); | |||||
int methodId = in.readInt(); | |||||
Exception err = null; | |||||
Object rvalue = null; | |||||
try { | |||||
ExportedObject eo = exportedObjects.get(objectId); | |||||
Object[] args = readParameters(in); | |||||
rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object, | |||||
args)); | |||||
} | |||||
catch(Exception e) { | |||||
err = e; | |||||
logging2(e.toString()); | |||||
} | |||||
outs.write(okHeader); | |||||
ObjectOutputStream out = new ObjectOutputStream(outs); | |||||
if (err != null) { | |||||
out.writeBoolean(false); | |||||
out.writeUTF(err.toString()); | |||||
} | |||||
else | |||||
throws IOException { | |||||
try (ObjectInputStream in = new ObjectInputStream(ins)) { | |||||
int objectId = in.readInt(); | |||||
int methodId = in.readInt(); | |||||
Exception err = null; | |||||
Object rvalue = null; | |||||
try { | try { | ||||
out.writeBoolean(true); | |||||
out.writeObject(rvalue); | |||||
} | |||||
catch (NotSerializableException e) { | |||||
ExportedObject eo = exportedObjects.get(objectId); | |||||
Object[] args = readParameters(in); | |||||
rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object, | |||||
args)); | |||||
} catch (Exception e) { | |||||
err = e; | |||||
logging2(e.toString()); | logging2(e.toString()); | ||||
} | } | ||||
catch (InvalidClassException e) { | |||||
logging2(e.toString()); | |||||
outs.write(okHeader); | |||||
try (ObjectOutputStream out = new ObjectOutputStream(outs)) { | |||||
if (err != null) { | |||||
out.writeBoolean(false); | |||||
out.writeUTF(err.toString()); | |||||
} else { | |||||
try { | |||||
out.writeBoolean(true); | |||||
out.writeObject(rvalue); | |||||
} catch (NotSerializableException | InvalidClassException e) { | |||||
logging2(e.toString()); | |||||
} | |||||
} | |||||
out.flush(); | |||||
} | } | ||||
out.flush(); | |||||
out.close(); | |||||
in.close(); | |||||
} | |||||
} | } | ||||
private Object[] readParameters(ObjectInputStream in) | private Object[] readParameters(ObjectInputStream in) | ||||
} | } | ||||
private void lookupName(String cmd, InputStream ins, OutputStream outs) | private void lookupName(String cmd, InputStream ins, OutputStream outs) | ||||
throws IOException | |||||
{ | |||||
ObjectInputStream in = new ObjectInputStream(ins); | |||||
String name = DataInputStream.readUTF(in); | |||||
ExportedObject found = exportedNames.get(name); | |||||
outs.write(okHeader); | |||||
ObjectOutputStream out = new ObjectOutputStream(outs); | |||||
if (found == null) { | |||||
logging2(name + "not found."); | |||||
out.writeInt(-1); // error code | |||||
out.writeUTF("error"); | |||||
} | |||||
else { | |||||
logging2(name); | |||||
out.writeInt(found.identifier); | |||||
out.writeUTF(found.object.getClass().getName()); | |||||
throws IOException { | |||||
try (ObjectInputStream in = new ObjectInputStream(ins)) { | |||||
String name = DataInputStream.readUTF(in); | |||||
ExportedObject found = exportedNames.get(name); | |||||
outs.write(okHeader); | |||||
try (ObjectOutputStream out = new ObjectOutputStream(outs)) { | |||||
if (found == null) { | |||||
logging2(name + "not found."); | |||||
out.writeInt(-1); // error code | |||||
out.writeUTF("error"); | |||||
} else { | |||||
logging2(name); | |||||
out.writeInt(found.identifier); | |||||
out.writeUTF(found.object.getClass().getName()); | |||||
} | |||||
out.flush(); | |||||
} | |||||
} | } | ||||
out.flush(); | |||||
out.close(); | |||||
in.close(); | |||||
} | } | ||||
} | } | ||||
public Object lookupObject(String name) throws ObjectNotFoundException | public Object lookupObject(String name) throws ObjectNotFoundException | ||||
{ | { | ||||
try { | try { | ||||
Socket sock = new Socket(servername, port); | |||||
OutputStream out = sock.getOutputStream(); | |||||
out.write(lookupCommand); | |||||
out.write(endofline); | |||||
out.write(endofline); | |||||
int n; | |||||
String classname; | |||||
try (Socket sock = new Socket(servername, port)) { | |||||
OutputStream out = sock.getOutputStream(); | |||||
out.write(lookupCommand); | |||||
out.write(endofline); | |||||
out.write(endofline); | |||||
ObjectOutputStream dout = new ObjectOutputStream(out); | |||||
dout.writeUTF(name); | |||||
dout.flush(); | |||||
ObjectOutputStream dout = new ObjectOutputStream(out); | |||||
dout.writeUTF(name); | |||||
dout.flush(); | |||||
InputStream in = new BufferedInputStream(sock.getInputStream()); | |||||
skipHeader(in); | |||||
ObjectInputStream din = new ObjectInputStream(in); | |||||
int n = din.readInt(); | |||||
String classname = din.readUTF(); | |||||
din.close(); | |||||
dout.close(); | |||||
sock.close(); | |||||
InputStream in = new BufferedInputStream(sock.getInputStream()); | |||||
skipHeader(in); | |||||
ObjectInputStream din = new ObjectInputStream(in); | |||||
n = din.readInt(); | |||||
classname = din.readUTF(); | |||||
din.close(); | |||||
dout.close(); | |||||
} | |||||
if (n >= 0) | if (n >= 0) | ||||
return createProxy(n, classname); | return createProxy(n, classname); | ||||
* | * | ||||
* lookupObject() has the same problem. | * lookupObject() has the same problem. | ||||
*/ | */ | ||||
Socket sock = new Socket(servername, port); | |||||
OutputStream out = new BufferedOutputStream( | |||||
sock.getOutputStream()); | |||||
out.write(rmiCommand); | |||||
out.write(endofline); | |||||
out.write(endofline); | |||||
try (Socket sock = new Socket(servername, port)) { | |||||
OutputStream out = new BufferedOutputStream(sock.getOutputStream()); | |||||
out.write(rmiCommand); | |||||
out.write(endofline); | |||||
out.write(endofline); | |||||
ObjectOutputStream dout = new ObjectOutputStream(out); | |||||
dout.writeInt(objectid); | |||||
dout.writeInt(methodid); | |||||
writeParameters(dout, args); | |||||
dout.flush(); | |||||
ObjectOutputStream dout = new ObjectOutputStream(out); | |||||
dout.writeInt(objectid); | |||||
dout.writeInt(methodid); | |||||
writeParameters(dout, args); | |||||
dout.flush(); | |||||
InputStream ins = new BufferedInputStream(sock.getInputStream()); | |||||
skipHeader(ins); | |||||
ObjectInputStream din = new ObjectInputStream(ins); | |||||
result = din.readBoolean(); | |||||
rvalue = null; | |||||
errmsg = null; | |||||
if (result) | |||||
rvalue = din.readObject(); | |||||
else | |||||
errmsg = din.readUTF(); | |||||
din.close(); | |||||
dout.close(); | |||||
sock.close(); | |||||
InputStream ins = new BufferedInputStream(sock.getInputStream()); | |||||
skipHeader(ins); | |||||
ObjectInputStream din = new ObjectInputStream(ins); | |||||
result = din.readBoolean(); | |||||
rvalue = null; | |||||
errmsg = null; | |||||
if (result) { | |||||
rvalue = din.readObject(); | |||||
} else { | |||||
errmsg = din.readUTF(); | |||||
} | |||||
din.close(); | |||||
dout.close(); | |||||
} | |||||
if (rvalue instanceof RemoteRef) { | if (rvalue instanceof RemoteRef) { | ||||
RemoteRef ref = (RemoteRef)rvalue; | RemoteRef ref = (RemoteRef)rvalue; |
URLConnection con = url.openConnection(); | URLConnection con = url.openConnection(); | ||||
con.connect(); | con.connect(); | ||||
int size = con.getContentLength(); | int size = con.getContentLength(); | ||||
InputStream s = con.getInputStream(); | |||||
if (size <= 0) | |||||
b = readStream(s); | |||||
else { | |||||
b = new byte[size]; | |||||
int len = 0; | |||||
do { | |||||
int n = s.read(b, len, size - len); | |||||
if (n < 0) { | |||||
s.close(); | |||||
throw new IOException("the stream was closed: " | |||||
+ classname); | |||||
} | |||||
len += n; | |||||
} while (len < size); | |||||
try (InputStream s = con.getInputStream()) { | |||||
if (size <= 0) { | |||||
b = readStream(s); | |||||
} else { | |||||
b = new byte[size]; | |||||
int len = 0; | |||||
do { | |||||
int n = s.read(b, len, size - len); | |||||
if (n < 0) { | |||||
throw new IOException("the stream was closed: " | |||||
+ classname); | |||||
} | |||||
len += n; | |||||
} while (len < size); | |||||
} | |||||
} | } | ||||
s.close(); | |||||
return b; | return b; | ||||
} | } | ||||
} | } | ||||
final void process(Socket clnt) throws IOException { | final void process(Socket clnt) throws IOException { | ||||
InputStream in = new BufferedInputStream(clnt.getInputStream()); | |||||
String cmd = readLine(in); | |||||
logging(clnt.getInetAddress().getHostName(), | |||||
new Date().toString(), cmd); | |||||
while (skipLine(in) > 0){ | |||||
} | |||||
OutputStream out = new BufferedOutputStream(clnt.getOutputStream()); | |||||
try { | |||||
doReply(in, out, cmd); | |||||
} | |||||
catch (BadHttpRequest e) { | |||||
replyError(out, e); | |||||
try (InputStream in = new BufferedInputStream(clnt.getInputStream())) { | |||||
String cmd = readLine(in); | |||||
logging(clnt.getInetAddress().getHostName(), | |||||
new Date().toString(), cmd); | |||||
while (skipLine(in) > 0) {} | |||||
try (OutputStream out | |||||
= new BufferedOutputStream(clnt.getOutputStream())) { | |||||
try { | |||||
doReply(in, out, cmd); | |||||
} catch (BadHttpRequest e) { | |||||
replyError(out, e); | |||||
} | |||||
out.flush(); | |||||
} | |||||
} | } | ||||
out.flush(); | |||||
in.close(); | |||||
out.close(); | |||||
clnt.close(); | clnt.close(); | ||||
} | } | ||||
File file = new File(filename); | File file = new File(filename); | ||||
if (file.canRead()) { | if (file.canRead()) { | ||||
sendHeader(out, file.length(), fileType); | sendHeader(out, file.length(), fileType); | ||||
FileInputStream fin = new FileInputStream(file); | |||||
byte[] filebuffer = new byte[4096]; | |||||
for (;;) { | |||||
len = fin.read(filebuffer); | |||||
if (len <= 0) | |||||
break; | |||||
out.write(filebuffer, 0, len); | |||||
try (FileInputStream fin = new FileInputStream(file)) { | |||||
byte[] filebuffer = new byte[4096]; | |||||
for (;;) { | |||||
len = fin.read(filebuffer); | |||||
if (len <= 0) { | |||||
break; | |||||
} | |||||
out.write(filebuffer, 0, len); | |||||
} | |||||
} | } | ||||
fin.close(); | |||||
return; | return; | ||||
} | } | ||||
// then Class.getResourceAsStream() is tried. | // then Class.getResourceAsStream() is tried. | ||||
if (fileType == typeClass) { | if (fileType == typeClass) { | ||||
InputStream fin | |||||
= getClass().getResourceAsStream("/" + urlName); | |||||
if (fin != null) { | |||||
ByteArrayOutputStream barray = new ByteArrayOutputStream(); | |||||
byte[] filebuffer = new byte[4096]; | |||||
for (;;) { | |||||
len = fin.read(filebuffer); | |||||
if (len <= 0) | |||||
break; | |||||
barray.write(filebuffer, 0, len); | |||||
try (InputStream fin | |||||
= getClass().getResourceAsStream("/" + urlName)) { | |||||
if (fin != null) { | |||||
ByteArrayOutputStream barray = new ByteArrayOutputStream(); | |||||
byte[] filebuffer = new byte[4096]; | |||||
for (;;) { | |||||
len = fin.read(filebuffer); | |||||
if (len <= 0) { | |||||
break; | |||||
} | |||||
barray.write(filebuffer, 0, len); | |||||
} | |||||
byte[] classfile = barray.toByteArray(); | |||||
sendHeader(out, classfile.length, typeClass); | |||||
out.write(classfile); | |||||
return; | |||||
} | } | ||||
byte[] classfile = barray.toByteArray(); | |||||
sendHeader(out, classfile.length, typeClass); | |||||
out.write(classfile); | |||||
fin.close(); | |||||
return; | |||||
} | } | ||||
} | } | ||||
attrs.put(new Attributes.Name("Can-Retransform-Classes"), "true"); | attrs.put(new Attributes.Name("Can-Retransform-Classes"), "true"); | ||||
attrs.put(new Attributes.Name("Can-Redefine-Classes"), "true"); | attrs.put(new Attributes.Name("Can-Redefine-Classes"), "true"); | ||||
JarOutputStream jos = null; | |||||
try { | |||||
jos = new JarOutputStream(new FileOutputStream(jar), manifest); | |||||
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jar), manifest)) { | |||||
String cname = HotSwapAgent.class.getName(); | String cname = HotSwapAgent.class.getName(); | ||||
JarEntry e = new JarEntry(cname.replace('.', '/') + ".class"); | |||||
jos.putNextEntry(e); | |||||
ClassPool pool = ClassPool.getDefault(); | |||||
CtClass clazz = pool.get(cname); | |||||
jos.putNextEntry(new JarEntry(cname.replace('.', '/') + ".class")); | |||||
CtClass clazz = ClassPool.getDefault().get(cname); | |||||
jos.write(clazz.toBytecode()); | jos.write(clazz.toBytecode()); | ||||
jos.closeEntry(); | jos.closeEntry(); | ||||
} | } | ||||
finally { | |||||
if (jos != null) | |||||
jos.close(); | |||||
} | |||||
return jar; | return jar; | ||||
} | } |
private static byte[] toBytecode(ClassFile cf) throws IOException { | private static byte[] toBytecode(ClassFile cf) throws IOException { | ||||
ByteArrayOutputStream barray = new ByteArrayOutputStream(); | ByteArrayOutputStream barray = new ByteArrayOutputStream(); | ||||
DataOutputStream out = new DataOutputStream(barray); | |||||
try { | |||||
try (DataOutputStream out = new DataOutputStream(barray)) { | |||||
cf.write(out); | cf.write(out); | ||||
} | } | ||||
finally { | |||||
out.close(); | |||||
} | |||||
return barray.toByteArray(); | return barray.toByteArray(); | ||||
} | } | ||||
new File(dir).mkdirs(); | new File(dir).mkdirs(); | ||||
} | } | ||||
DataOutputStream out = new DataOutputStream(new BufferedOutputStream( | |||||
new FileOutputStream(filename))); | |||||
try { | |||||
try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream( | |||||
new FileOutputStream(filename)))) { | |||||
cf.write(out); | cf.write(out); | ||||
} | } | ||||
catch (IOException e) { | catch (IOException e) { | ||||
throw e; | throw e; | ||||
} | } | ||||
finally { | |||||
out.close(); | |||||
} | |||||
} | } | ||||
} | } |