I’m trying to make an auto-updating client. The jarred client will go to the server and ask for an update file. The server will send over the update file. When the update file(containing the jar file which has been converted into a byte array) arrives, the client will check whether it has the newest version of the client jar(the one in the update file). The reference “in” is a socket connected to the server, by the way.
UpdateFile uf = (UpdateFile) in.readObject();
System.out.println("Client checking if update needed");
if (!uf.getVersion().equals(myVersion)) {
System.out.println("Client needed update");
uf.update(updateLocation);
}
If it does not have the newest jar, it will call the function update(String whereToUpdate) in UpdateFile. This will delete the old jar file(The one calling the function update()!) and replace it by writing the byte[] to the same position.
public void update(String location) {
try {
boolean b = (new File(location)).delete();
System.out.println("removed old jar file");
updateJar.writeBytes(location);
} catch (Exception ex) {
ex.printStackTrace();
}
}
In this code, updateJar is a NetworkingFile(my own class). This NetworkingFile pretty converts non-serializable objects into a byte[], is sent to the receiver, and writes the file back to disk.
public class NetworkingFile implements Serializable{
byte[] cArray;
String name;
public NetworkingFile(File f, String fileName) {
name = fileName;
compressFile(f);
}
public NetworkingFile(byte[] b, String fileName) {
cArray = b;
name = fileName;
}
public void compressFile(File f) {
cArray = new byte[(int)f.length()];
try {
FileInputStream inputReader = new FileInputStream(f);
BufferedInputStream fileReader = new BufferedInputStream(inputReader);
fileReader.read(cArray, 0, cArray.length);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public String getFileName() {
return name;
}
public byte[] getCompressedFile() {
return cArray;
}
public void writeBytes(String location) {
try {
File writeFile = new File(location);
FileOutputStream writer = new FileOutputStream(writeFile);
writer.write(cArray);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
This code doesn’t give an error when compiling or executing the FIRST jar. However, when the jar is finished updating, I quit the program and try to run it using “java -jar filename.jar”. However, I get this error on running:
Error: Invalid or corrupt jarfile DropBoxClient.jar
Any ideas on what might cause this? All help will be appreciated.
A few things here.
The first one is that you are not closing your FileOutputStream. If you don’t close of flush it, the program may end without writing everything to disk.
Second one, fileReader.read is not GUARANTEED to read that many bytes, for a number of reasons it may return before actually reading that much bytes. That’s why it returns an int with the number of bytes actually read. (see javadocs here)
The recommended way for copying a file from one file to another is rather different than the one you implemented here, see for example this source code example.
I would suggest you to read a bit more about how Java streams work, they may seem simpler than they are.