I'm trying to limit changes from a jar file. I introduced a fix on the code, a very small fix in a single file. Javac compiler generates the new .class file and I plan to replace ONLY this single file in the jar (we had problems with the build and are unsure if the current build matches the production build).
I'm a C++ pro, but java... not so much. I wouldn't dare to do this in C++ as optimizers inline a lot of stuff from object files and static libs. I'm under the impression I can do this with no great consequences in java.
Any advice?
I usually hot deploy files on server, that creates no problem in JAVA. You can do it as long as your compiler version is same as the other files. It would not be a problem.
The Java Language Specification defines binary compatibility between class files. In general, class files tend to be much more compatible than they would be in C, so you'll probably be ok. However, there are a few gotchas, such as static final fields (constants) which are inlined by the compiler.
In any case, the situation in which you are not sure what code code you have running in production, I would consider to be very dangerous, and try to fix as soon as possible.
Related
I have a question which I'm pretty confused from.
I am aware of the differences between Java Runtime Enviroment and Java Developement Kit.
I'm writing a program that uses the ToolProvider.getSystemJavaCompiler() method to compile java code from within the code.
Now, I've been answered that I can't compile code from client side if my client doesn't have JDK installed. My main question is, how can I do that? I don't want my clients having to install JDK on their computer just to run my program.
Thanks in advance!
You need to compile it on your system, and distribute the class file of corresponding java source file to anyone.
That class file doesn't require JDK but JRE must be installed on that system to run the class file.
If you want to compile code, you need a compiler, so if the user can't be expected to have the compiler you need, you'll simply have to bundle it.
I really can't say I know how to bundle the standard javac compiler, though it's probably possible, strictly speaking, to find the Jar file that contains it and bundle that along with your code. No idea how robust such a solution would be, though.
But depending on your needs, you may not need the standard javac. There are tons of byte-code generation libraries out there, with more or less high-level functionality. I wouldn't really want to recommend anything that I have no personal experience with, but examples include Byte Buddy or ASM. You could probably use ABCL too.
Eclipse's compiler is worth a look as well.
There is also an so question here.
So there really is no way to do what it is you are wanting to do unless you bundle the compiler itself with you application, or unless you find a library that has all of the Java compiler code in it already so it doesn't have to use the JDK compiler, you will not get what you want, and what you want is the ability to turn a String containing source code into a Java class.
I do not understand what you wish to accomplish, but the BEST option I can give you is asm. If you are up for the task, you can manually write new classes at runtime without the presence of the JDK compiler. HOWEVER, this does not involve you using a String full of source code and turning it into a Class object. This is you working at the low level with the Java bytecode for the most part.
This tutorial can get you started:
https://www.javaworld.com/article/2071777/design-patterns/add-dynamic-java-code-to-your-application.html
And here is the Java documentation for class files. You can use this to expand on what you learned from the first link:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
That is the only instance creating classes on the fly that I can give you. That being said, you could try writing your own Java compiler that can turn source code into classes without ever getting the Java compiler, but at that point you are literally recreating the Java compiler yourself, and I assure you that is no easy feat for one person.
First some reference:
1st Link
2nd link
The first article 1st Link mentions about compiling the Java files directly into JAR files and avoiding one step in the build process. Does anyone know this?
-Vadiraj
As you linked to my blog post I thought it was only fair to give you an update.
Compiling directly to a Jar is actually fairly simple to do. Basically you extend
javax.tools.ForwardingJavaFileObject
Then override openOutputStream method and direct it to your Jar. As the Java Compiler is highly concurrent but writing to a jar file is highly sequential I'd recommend that you buffer to byte arrays and then have a background thread that writes the byte arrays as they arrive.
I do exactly this is my experimental build tool JCompilo https://code.google.com/p/jcompilo/
This tool is completely undocumented but crazy fast. Currently it's about 20-80% faster than any other Java build tool and about 10x faster than the Scala compiler for the same code.
As the author is talking about extending the compiler itself, it is possible that he has knowledge of the built-in capabilities of the compiler (that is what the compiler is capable of, maybe with a little encouragement by tweaking the code).
Right now I’m investigating extending the Java 6 compiler to remove the unneeded file exists checks and possible jaring the class files directly in the compiler. [emphasis mine]
That capability, however, is certainly not supported officially (no documentation exist about it on the javac webpage).
At best, the feature is compiler dependent; possibly requiring modification of the compiler's source code.
I require a source code obfuscator for Java that is working on windows 7.
Because I plan to release a closed source library in GWT it really has to be an obfuscator that outputs source and does not process ready to use .class files. The result files need to be .java files.
The only obfuscator that is Java-to-Java instead of .class as a result is Java Source Code Obfuscator from Semantic Design.
But sadly it seems this one does not work on Windows 7.
What about compile it into class files with all the debugging symbols stripped and then run a decompiler on the resulting class files? Example decompiler
Despite the existence of some quality work out there, I assure you Java obfuscation will NOT stop someone who is determined to decompile your code. Understand that all you are buying is a bit of time. If they have your class files in hand and choose to decompile them, it won't take long before they have your source code.
If you don't trust your customer, don't give them the class files. Come up with a different solution. More and more companies are moving to services as a way to keep their source code in house and still make their monies.
Most Java source codes are self obfuscated, nobody can understand them.
There are no effective obfuscators, the silly things they do do not deter anyone determined to steal your code. This is a false market based on false fears. If the threats were real, there will be de-obfuscators, selling for much higher price than obfuscators.
If you really want to obfuscate your code, don't use meaningless symbols, use misleading symbols.
I want to hand over a small Java app as a runnable jar but I do not want anybody to have access to my source code. Am I right in presuming that there is no source code (.java files) included with a jar file?
User269799
Assuming you don't put the java files in the jar file, they're not going to magically appear :) You can include anything you like in the jar file of course. You can list the contents to check:
jar tvf foo.jar
Note that Java can be decompiled pretty easily though - so while any recipients wouldn't have access to your actual source code with comments etc, they could see your logic pretty clearly. You may want to use an obfuscator to help protect your IP. Personally I try to avoid obfuscators - given how hard most of us find to maintain code when we do have the real source with commments and tests, imagine how hard it is when you don't have those things :) It's your call though. Just make sure you test obfuscated code thoroughly - there can be subtle issues, particularly if you use reflection.
If a computer can run it, a human can reverse engineer it, and it is not particularly hard for Java.
So technical protection simply won't work. You need legal protection in form of a binding contract or similar. You may even put your works under the GPL except for those paying you, which is sufficient for most businesses to avoid stealing your work.
What situation exactly do you want to avoid?
Jar files usually only include .class files, which are java bytecode files, as well as resources. However, to be a little more secure about your code, you'll want to turn off debugging information and if you really want to be secure, run it through an obfuscator.
Edit: berry120's comment is right - they can contain source files, but usually they do not. I just want to clarify for any future readers of this. It depends on the settings of the tool you use to generate the jar.
You are right, there is no source code in the jar (unless you configure your build system to specifically put it in there). But you are always at the risk you code gets decompiled from the bytecode. An obfuscater might help here.
Yes. Usually, jars contain only byte-compiled .class files. That said, they can contain source code as well—it depends on what you (or your tools, respectively) put into them.
Note, however, that decompilation works pretty well on .class files, so don't make anything security-related rely on code obfuscation techniques such as this one.
Normally there isn't but you can use the jar -tvf <filename> command to check it.
However I have to warn you that it's extremely easy to decompile most .class files into reasonably readable java source code.
To avoid this, you'll have to use an obfuscator, but that needs some extra effort on your behalf. (E.g. RetroGuard.)
Having said that, ask yourself the question: "Is my code really that valuable or special that I need to do all this?" Usually the answer is no, most of the code we write is nothing special.
You are are correct, however the .class files can easily be disassembled to java code, and its pretty accurate in most cases.
If you really need it to be properly secure then you'll need to obfuscate.
It will depend on the way you generated that .jar, Eclipse does have an option to include .java files on the .jar but it is disabled by default and you have to activate it if wanted.
Jar files might contain the source (you can choose whether to include it or not) so not including the source specifically isn't an issue. What you need to be aware of though is people potentially reverse engineering the class files that will be in the jar file.
You can get around this usng an obfuscator such as yGuard which easily hooks in as an ant task, but as others have said, is your code really that important that no-one else sees it?
The .jar file does not include source code, only the bytecode (.class). But as the byte code is machine independent, it can be decompiled very easily. There is no way to prevent others to access your source code.
So, I've been programming for a while now, but since I haven't worked on many larger, modular projects, I haven't come across this issue before.
I know what a .dll is in C++, and how they are used. But every time I've seen similar things in Java, they've always been packaged with source code. For instance, what would I do if I wanted to give a Java library to someone else, but not expose the source code? Instead of the source, I would just give a library as well as a Javadoc, or something along those lines, with the public methods/functions, to another programmer who could then implement them in their own Java code.
For instance, if I wanted to create a SAX parser that could be "borrowed" by another programmer, but (for some reason--can't think of one in this specific example lol) I don't want to expose my source. Maybe there's a login involved that I don't want exploited--I don't know.
But what would be the Java way of doing this? With C++, .dll files make it much easier, but I have never run into a Java equivalent so far. (I'm pretty new to Java, and a pretty new "real-world" programmer, in general as well)
Java .jar library is the Java equivalent of .dll, and it also has "Jar hell", which is the Java version of "dll hell"
http://en.wikipedia.org/wiki/JAR_(file_format)
Google JAR files.
Edit: Wikipedia sums it up nicely: http://en.wikipedia.org/wiki/JAR_%28file_format%29
Software developers generally use .jar files to distribute Java applications or libraries...
A jar is just a uncompressed zip of your classes. All classes can be easily decompiled and viewed. If you really don't want to share your code, you might want to look at obfuscating your code.
The Java analog to a DLL is the .jar file, which is a zip file containing a bunch of Java .class files and (perhaps) other resources. See Sun's, er, Oracle's documentation.
Java's simple moto 'Write Once, Run anywhere'. create your all java classes as jar file but there are possibilities that still some one can see the Java code by using Decompilers. To prevent someone really looking at your code then Obfuscate the jar using the below link.
Java Obfuscation
You could publish a collection of compiled *.class files.
The most common way to package up Java code is to use a ".jar" file. A .jar file is basically just a .zip file.
To distribute just your compiled code, you'll want to build a .jar that contains your .class files. If you want to additionally distribute the source code, you can include the .java files in a separate area of the .jar.
There are a lot of tools and tutorials out there that explain how to build a .jar.
Technically, you can compile Java bytecode down to native code and create a conventional DLL or shared library using an Ahead-Of-Time compiler.
However, that DLL would need the Java runtime specific to the AOT compiler, and two Java runtimes may not coexist in one process. Also, one would have to employ JNI to make any use of that DLL.
Unfortunately, obfuscation has too many weaknesses...
your tittle doesn't match your comment....
simple have a source jar and a code jar. but, as other people pointed out you can obfuscate the code if you don't want people to read it, it's a pain for other people using your library as they would need the mappings in order to compile and the obfuscator.
A dll is a shared library (from what I read gets instantiated one time across multiple processes)
A jar is a shared library (code gets instantiated per process from the same file)
So to answer your title question there doesn't appear to be one built into java. A library could be made and then supported on all 3 major os's to have a dll equivalent version in java. But, the reason why java made it a new instance per program is for security / sanity reasons. there are custom class loaders, asm and reflection that other programs can modify the classes on load. So if your program does any of these things it could mess up other processes.
You don't have to distribute your source code. You can distribute compiled .class files, which contain human-unreadable bytecode. You can bundle them into .jar files, which are just zip files, and are roughly Java equivalent of native .dll files.
Note taht .class files can be easily decompiled (although decompilers cannot recover 100% of information from sources). To make decompilation more difficult, you can use obfuscator to make sources much less legible.