[SOLVED] Checksum

Is there a library anyone can recommend for checking checksums for my clients auto-updater?

Would like to be able to integrate it into the distribution build process as well by having it create the checksums on a filetree during the distribution build and spit out a text file that I could include on the update server.

1 Like

You are calling this from code, from build file, from command line or all of the above?

Edit: because Java already includes checksum: https://docs.oracle.com/javase/7/docs/api/java/util/zip/Checksum.html

Build file during distro build, code when client downloads the file.

Build file is gradle?

yes

So are you just looking for a wrapper for the existing built in checksum stuff that does the stream handling for you?

I have not ever used this before with the exception of manually checking a file using windows cmd line a couple times.

Thought there may be something like a library I could depends in gradle and run a simple command to write out a file or files in a dir and also use it to check from the client when downloading.

Wasn’t aware of the java interface.

From gradle there is this:

…but I’ve never tried it.

Guava may have some utilities that make it easier to work with the IO and stuff. I haven’t look to see if newer java has added anything streams related for checksums.

I was just making sure there wasn’t a reason you were steering away from the built in Checksum stuff other than not knowing it was there.

I will try this and let you know how it goes.

@mitm did you create your own updater or using a third-party library?

My own.

1 Like

Have you followed any tutorials or docs? If so would you mind sharing a link please? :slightly_smiling_face:

For building the auto updater?

Yes

Not sure how much this will help as I started out with theory on how to make it work,

Creating An Updater In Java - Java Tutorials | Dream.In.Code

but I use none of this code in the updater. I use javafx, he uses swing also.

I used the java io classes mentioned in the eugenep/tutorials ResumableDownload.java file as an example of how you can download but not as written.


I went with a different approach where if the file did not download fully its considered a critical error and the program will bail, starting over on the next try initiated by the user rather than resuming where it left off.

I don’t know how helpful any of that is as I have spent 8 months writing the updater. I found it was extremely complicated to do it in a way that was safe and cross platform.

In case people are wondering why go to all that trouble, I didn’t feel comfortable with the free options available and the pay ones are scary expensive for a closed source project.

I want to actually open it up to the public once finished but for selfish reasons. The main one being I believe the more eyes that see it the better and safer it will be. Key word here is safe.

I had no idea how complicated this was when I started but that’s why they charge what they do I found out.

Its not as simple as it sounds and once you pull that string, it leads you into some real crazy places, or at least it did for me. Its been a hell of a ride.

1 Like

I see, thanks so much for the info and the links. :slightly_smiling_face:

I will also need an updater for my game. If it turns out to be complex as you said I may try a third-party like Getdown or update4j.

I just looked at update4j again and it looks like they have done alot of work recently updating it.

They seem to take a different approach than me as I made my updater agnostic of java, modules, class path or anything really. I use paths. I write the paths used by an archive to a version file when building the app or updater. This allowed me to use jpackage or any distribution method, like zip files built by the distribution plugin, interchangeably. The calling app uses jpackage and the updater is a standard distribution created by the distribution plugin that gets extracted into the calling app’s image during build via gradle.

All I have to do to force an update is extract the archive of either one of these on the update server. Only different versions of any file gets downloaded though. I added an extra files download argument for un-versioned files that must be downloaded, like startscripts for example. They will always change when a version of some jar changes.

As for starting the app after download, the calling app is responsible for moving any new updater files and starting the updater and the updater is responsible for moving the calling app files and starting the calling app, each using a path to a start scripts or exe that either jpackage or the distribution plugin builds. The updater does all the downloading for both.

Each uses the exact same paths found in whatever version file it’s interested in to locate the file on the update server and move the downloaded file on the local machine.

This method requires you to know where the calling app lives though, like on windows I force install into AppData and other os in user home.

1 Like

Forgot I changed the updater to be packaged using jpackage. Have been busy for two months with life.

Still doesn’t change anything I wrote much, just different folder structure vs standard zip. The updater is modular but the calling app is non-modular.

Anyway, works anyway you want it to as its path based.

Edit: The updater app image still gets zipped and extracted into the calling apps jpackage image prior to running final jpackage build command as explained above. This allows the updater to be installed when the calling app is installed on the users machine the first time.

1 Like

For the Outside Engine, we used CRC32 as it is very fast. The engine verifies all assets on startup.
Here is the code:

public class Checksum {
    public static long getChecksum(final File file) {
        try (final CheckedInputStream in = new CheckedInputStream(new BufferedInputStream(new FileInputStream(file)), new CRC32())) {
            return tryGetChecksum(in);
        } catch (final IOException e) {
            return 0L;
        }
    }

    public static long tryGetChecksum(final CheckedInputStream in) throws IOException {
        final byte[] buf = new byte[4096];
        for (int bytesRead; (bytesRead = in.read(buf)) != -1; );
        return in.getChecksum().getValue();
    }
}

The great thing about this is the speed and that it is native to java.

2 Likes

Started learning this and found that I can simply use ant with gradle to write the files.

Simple one liner added to what I use to write the file versions.

        tree.visit { file ->
            if (!file.isDirectory()) {
                //Add version line
                prtWriter.println("$file.relativePath")
                //Write to file                
                fileWriter.write(strWriter.toString())
                //Create checksum
                ant.checksum(file: "${buildDir}/${packageDir}/$file.relativePath", algorithm: "SHA-256")
            }
        }