1

Java class files inside jars can be easily replaced and modified. For instance, the following command can be used to replace a compiled class file within a jar:

jar uf JarFile.jar com\something\Class.class

If the class file was replaced with a file such that no dependencies were broken, then the code is still able to execute. The same happens with class files that are not inside jars.

Is there any way to validate a set of class files (whether inside a jar or not) to see if all their dependencies are present and not broken?

I do not want to prevent class files from being modified but rather to be able to verify that changes are valid (with respect to dependencies). The compiler does this check (dependency-check) at compile time, but once the classes are compiled, how can one verify the class files themselves?

Eugenio De Hoyos
  • 1,755
  • 16
  • 22
  • 1
    **all their dependencies**? Including `jdk`? Transitively or just 1st level? This may be a difficult problem to solve – Miserable Variable Jul 17 '12 at 23:43
  • Take a look at [one-jar](http://one-jar.sourceforge.net) it creates a single jar with no external dependencies (I assume except for JDK) but you may be able to use the same approach (and code) for validation. – Miserable Variable Jul 17 '12 at 23:50
  • @MiserableVariable: 1st level is good enough... – Eugenio De Hoyos Jul 18 '12 at 00:29
  • @MiserableVariable: Interesting... Not an exact solution, but it (one-jar) might be adapted for this... – Eugenio De Hoyos Jul 18 '12 at 00:33
  • 1
    @EugenioDeHoyos it was long before you posted this question, even after 8 years, I have a difficulty to find any solution for this problem. Do you remember/know a solution? thanks – Doston Apr 14 '20 at 07:47
  • @Dosto Thank you for the shoutout! As far as I know, there's no way to do this out-of-the-box. You could build a custom tool to do it by manually loading all classes in the JAR, but I strongly recommend against it, since all of this is an "anti-pattern". Even though the JVM allows you to do this, it doesn't mean you should do it. This is both a weakness and a strength of Java. Thankfully I no longer work for the team and company where "class patching" was a standard practice (as a workaround to deal with extremely slow builds). I hope you too find a way to avoid this practice altogether. – Eugenio De Hoyos Apr 15 '20 at 21:23

3 Answers3

0

You might have sealing and signing JARs in mind.

Update:

Apparently I've missed the mark with my first guess.

What do you plan to do if they're not? If they're a 3rd party, I'd say that you've got little choice besides reporting to the bug database that the download is bad.

If you mean "I want to make sure that all their 3rd party JAR dependencies are correct", you've got a much bigger problem. Most downloads that I know of (e.g. Spring) make dependencies available using Maven. That's the best you can do.

If you mean you want to check your own dependencies, I'd say that testing would reveal any errors you've made.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Not quite... I do not want to prevent the jar contents from changing. Instead, I want to verify that changes to a jar are valid (with respect to dependencies). – Eugenio De Hoyos Jul 17 '12 at 23:35
-1

no, you cannot.

at least: not really. the problem is that java loads classes at runtime only when needed. so eventually it might be alright to remove a class from the jar file and as long as no code referencing that class is executed things run very smoothly.

consider this example:

class A{ public static void main( String args[] ){ out.println( "hello" ); } }
class B{}

compile this, put it in a jar, remove the B.class from it, no problem there :)

now you might think you can go through each .class file, check what classes it references and see if the files are all there. not only is this painful, it is also incomplete. you will never quite catch files loaded with reflection because their class names might be constructed just at runtime.

my advice: don't go there. if someone removes a class file it's their own fault. the best thing you can do is (but only if this really really worries you) try to catch ClassNotFoundExceptions at runtime (look into thread.setUncaughtExceptionHandler)

kritzikratzi
  • 19,662
  • 1
  • 29
  • 40
  • I understand what you are saying, but strong-typed dependency checks are performed by the compiler when java code is compiled into byte code. Why wouldn't there be an analogous check available for byte code as well? It should take the same effort (or less) to check this on byte code than it takes on raw source code... Aside from the question of whether one would want to do this or not, how confident are you that there's no practical way to do this? – Eugenio De Hoyos Jul 18 '12 at 00:26
  • there's no built in way except signing your jar. but i'm quite confident no one is ever going to remove a class file from your jar archive. i've been coding java for long long time and never heard this ever happening. anyways, i see you are very concerned :) you could 1.)before you create your jar archive, generate a textfile with a list of .class files; add this your jar and compare on startup. 2.) use some bytecode lib, like apache bcel (http://depfind.sourceforge.net/Manual.html) or dependency finder (http://commons.apache.org/bcel/manual.html) – kritzikratzi Jul 18 '12 at 10:44
-1

Just loading the class will ensure that.

user207421
  • 305,947
  • 44
  • 307
  • 483