I am working with a large Java web application from a commercial vendor. I've received a patch from the vendor in the form of a new .class file that is supposed to resolve an issue we're having with the software. In the past, applying patches from this vendor have caused new and completely unrelated problems to arise, so I want to understand the change being made even before applying it to a test instance.
I've got the two .class files side by side, the one extracted from the currently running version and the updated one from the vendor. JAD and JReversePro both decompile and disassemble (respectively) the two versions to the same output. However, the .class files are different sizes and I see differences in the output of od -x, so they're definitely not identical.
What other steps could I take to determine the difference between the two files?
Conclusion:
Thanks for the great responses. Since javap -c output is also identical for the two class files, I am going to conclude that Davr's right and the vendor sent me a placebo. While I'm accepting Davr's answer for that reason, it was Chris Marshall and John Meagher who turned me on to javap, so thanks to all three of you.
It's possible that they just compiled it with a new version of the java compiler, or with different optimization settings etc, so that the functionality is the same, and the code is the same, but the output bytecode is slightly different.
If you are looking for API level differences the javap tool can be a big help. It will output the method signatures and those can be output to a plain text files and compared using normal diff tools.
You could try using a diff tool (such as SourceGear's free DiffMerge tool) on the decompiled sources. That should pick up the file differences, although it will likely pick up "insignificant" differences, for example if variables have been named differently in the two versions.
http://www.sourcegear.com/diffmerge/
You can use javap (in $JDK_HOME/bin) to decompile java .class files. It will tell you (for example) the class file version among other things
Related
I've been working on a Maven project consisting entirely of Java, and lately started to mix Scala code into it.
I'm amazed by the great expressiveness Scala offers, the easy use of scala-maven-plugin, and especially the incredible interoperability between Java and Scala.
However, I hit one inconvenience; according to the Maven's convention, Java's source code goes into src/main/java, whereas Scala's into src/main/scala. I found it quite cumbersome because I have to frequently go back and forth Java and Scala source files and every time I have to traverse the deep hierarchy of package directories (I often close tabs to keep my editor from cluttered).
So the question is: Is it recommended to maintain separate directories src/main/java and src/main/scala? If so, why?
To add more background, I've been working on the web application framework Wicket, whose convention is to put the HTML files alongside with their corresponding Java files. If we keep the directories separated, naturally the HTML files are separated as well (I don't think putting Scala files and corresponding HTML files in different directories makes sense). And then it goes "why I can't find Foo.html? Oh, I was looking for the wrong directory."
The source files themselves are very easy to distinguish both by humans and by machines by inspecting their extensions. I configured pom.xml to handle both Java and Scala put together in src/main/java and it worked (compiles and runs). On the other hand, separating directories poses a risk of defining conflicting classes in Java and in Scala, a careless mistake.
Well, I don't want to name a directory java if it contained not only Java's but also Scala's. But this is the only point I can come up with for separating directories.
(Edit: I've come up with a workaround-interpretation; let us think java stands for Java Virtual Machine. In this way, having src/main/c doesn't contradict if we ever decided to use JNI because C doesn't run on JVM.)
Oh, and one more point; my project is not intended as an open-source project; development convenience is preferred than trying hard to follow conventions.
This question is inspired by this answer.
I'd say yes, re-use code as much as possible. Maybe in future you can use this Java piece somewhere else...
As you probably know, you can use Java in Scala projects but not Scala in Java projects. So in this specific example it will help you with (future?) Java projects. If you want to re-use a piece of your Java code you can do that in either Java projects as well as Scala projects.
So i.m.h.o. it doesn't stop at the src/main/... but you should really put them even in different components.
Btw, little side note: if I'm correct, Wicket allows you to put the html somewhere else too, even in a different project... I saw it being handy (only) once, where we had to create different frontend for different clients of us. The java code stayed the same, the wicket-id's as well, but the html changed everywhere. Though it did give us some problems as well using the Qwicky plugin, as it could not find the html files in our IDE anymore.
Whenever I build my app all classes (logically) are visible in the .jar that comes out of it.
Aswell as a class that holds information to my MYSQL server (for the app to connect to). But I dont want this information to be publicly visible!
How can I "hide" this code or "hide" the class?
Thanks!!
I think you mean you dont want someone to do reverse engineering with your .class inside your jar file. There are many decompilers that can do that.
So you would need to Obfuscate your code with an obfuscator utility.
The process of obfuscation will convert bytecode into a logical
equivalent version that is extremely difficult for decompilers to pick
apart. Keep in mind that the decompilation process is extremely
complicated and cannot be easily 'tweaked' to bypassed obfuscated
code. Essentially the process is as follows:
Compile Java source code using a regular compiler (ie. JDK)
Run the obfuscator, passing in the compiled class file as a
parameter. The result will be a different output file (perhaps with a
different extension).
This file, when renamed as a .class file, will be functionally
equivalent to the original bytecode. It will not affect performance
because a virtual machine will still be able to interpret it.
Here is an article describing this process in more detail and
introducing an early obfuscator, Crema:
http://www.javaworld.com/javaworld/javatips/jw-javatip22.html
I'm trying to create a process to patch our current java application so users only need to download the diffs rather than the entire application. I don't think I need to go as low level as a binary diff since most of the jar files are small, so replacing an entire jar file wouldn't be that big of a deal (maybe 5MB at most).
Are there standard tools for determining which files changed and generating a patch for them? I've seen tools like xdelta and vpatch, but I think they work at a binary level.
I basically want to figure out - which files need to be added, replaced or removed. When I run the patch, it will check the current version of the software (from a registry setting) and ensure the patch is for the correct version. If it is, it will then make the necessary changes. It doesn't sound like this would be too difficult to implement on my own, but I was wondering if other people had already done this. I'm using NSIS as my installer if that makes any difference.
Thanks,
Jeff
Be careful when doing this--I recommend not doing it at all.
The biggest problem is public static variables. They are actually compiled into the target, not referenced. This means that even if a java file doesn't change, the class must be recompiled or you will still refer to the old value.
You also want to be very careful of changing method signatures--you will get some very subtle bugs if you change a method signature and do not recompile all files that call that method--even if the calling java files don't actually need to change (for instance, change a parameter from an int to a long).
If you decide to go down this path, be ready for some really hard to debug errors (generally no traces or significant indications, just strange behavior like the number received not matching the one sent) on customer site that you cannot duplicate and a lot of pissed off customers.
Edit (too long for comment):
A binary diff of the class files might work but I'd assume that some kind of version number or date gets compiled in and that they'd change a little every compile for no reason but that could be easily tested.
You could take on some strict development practices of not using public final statics (make them private) and not every changing method signatures (deprecate instead) but I'm not convinced that I know all the possible problems, I just know the ones we encountered.
Also binary diffs of the Jar files would be useless, you'd have to diff the classes and re-integrate them into the jars (doesn't sound easy to track)
Can you package your resources separately then minimize your code a bit? Pull out strings (Good for i18n)--I guess I'm just wondering if you could trim the class files enough to always do a full build/ship.
On the other hand, Sun seems to do an okay job of making class files that are completely compatible with the previous JRE release, so they must have guidelines somewhere.
You may want to see if Java WebStart can help you as it is designed to do exactly those things you want to do.
I know that the documentation describes how to create and do incremental updates, but we deploy the whole application as it changes very rarely. It is then an issue of updating the JNLP when ready.
How is it deployed?
On a local network I just leave everything as .class files in a folder. The startup script uses robocopy or rsync to copy from network share to local. If any .class file is different it is synced down. If not, it doesn't sync.
For non-local network I created my own updater. It downloads a text file of md5sums and compares to local files. If different it pulls file down from http.
A long time ago the way we solved this was to used Classpath and jar files. Our application was built in a Jar file, and it had a launcher Jar file. The launcher classpath had a patch.jar that was read into the classpath before the main application.jar. This meant that we could update the patch.jar to supersede any classes in the main application.
However, this was a long time ago. You may be better using something like the Java Web Start type of approach, which offers more seamless application updating.
We need an accurate diff utility for Java and Javascript files, written in Java. It should be invokable from within an Eclipse (version 3.2 or 3.3) application. Preferably we need the Java source code for this utility also.
The utility should be able to compare two files (old and new, say) and determine the following accurately:
Number of LOC added to the new file
Number of LOC deleted from the old file
Number of LOC changed in the old file
Number of change deltas, i.e., contiguous blocks of code added/changed/deleted.
Eclipse has a very good diff/compare plugin installed by default. Have you looked into using and/or extending that (it's opensource)? I would not think that adding some statistics reporting to the existing plug-in would be all that difficult, though sometimes plug-in development (even just simple extension) can be deceiving.
Good luck.
See Diffj.
I needed a Java diff implementation and found this: http://javacook.darwinsys.com/javasrc/textproc/Diff.java which I adapted.
Has anyone used the noweb literate programming tool on a large Java project, where several source code files must be generated in different subdirectories? How did you manage this with noweb? Are there any resources and/or best practices out there?
Noweb will dump out files relative to the current working directory, or at the absolute path you specify. Just don't use * at the end of your filename (to avoid inserting the # preprocessor directives). I would recommend using %def with # to show where you define and use names.
<</path/to/file.java>>=
reallyImportantVariable += 1;
# %def reallyImportantVariable
noweb lets you reorder and (the real win) reuse snippets of code, which I don't think javac would understand.
I'd agree that since most people expect that you'll use javadoc, you're probably swimming against the stream to use noweb.
Literate Programming works its best if the generated intermediate code can point back to the original source file to allow debugging, and analyzing compiler errors. This usually means pre processor support, which Java doesn't support.
Additionally Literate Programming is really not necessary for Java, as the original need for a strict sequential order - which was what prompted Knuth to write a tool to put snippets together in the appropriate sequence - is not present. The final benefit of literate programming, namely being able to write prose about the code, is also available as Javadoc which allow you to put everything in as comments.
To me, there is no benefit in literate programming for Java, and only troubles (just imagine getting IDE support).
Any particular reason you are considering it?