Say I have a String containing the content of a .java file. Are any APIs out there that would allow me to compile this source file into a virtual .class file (i.e. generate and store the content in memory, NOT creating an actual physical .class file on disk)? And this "virtual" .class would then be loaded and executed in the JVM?
Edit 1: The only reason I want to do this is because sometimes, my application might not have the write permission.
Use the JavaCompiler for this. I think the trick will be to define a custom JavaFileManager.
Java does have a compilation API to compile files dynamically, but I'm not aware of an option that would not persist the class files to disk. You can always use a ClassLoader and load those classes dynamically and then use them. You might be able to load the classes in memory by overriding the getFileForOutput method.
Optionally, this file manager might consider the sibling as a hint for
where to place the output. The exact semantics of this hint is
unspecified. The JDK compiler, javac, for example, will place class
files in the same directories as originating source files unless a
class file output directory is provided. To facilitate this behavior,
javac might provide the originating source file as sibling when
calling this method.
Another option is to use an Interpreter like BeanShell that will run the java code for you. It executes script like code and can work in repl mode.
Related
I'm planning to dynamically execute a .class files/bytecode. I'm trying to achieve this by first creating an unpacker which loads the .class files and jumps to the main function in the .class file and executes it while the unpacker shuts down.
How do I achieve this using Java?
If you are using ZIP and if the classes (packages) are placed in its root, then it is not even needed to unpack it. You can use your archive directly:
java -classpath my.zip mypackage.MyClass
If you want to launch one Java code from another Java application, either use Runtime.exec(), which is simple but not quite reliable (you may need to know location of JRE or particular path in the system PATH), or, more reliable but also harder to implement, use class loader, let it load unpacked classes (you mentioned decryption, so classloader should also decrypt classes before loading them), select needed class via this class loader, then invoke the main method.
You could just write a single main class that calls other classes based on the arguments passed to it.
I'm trying to make a java program which executes java files and gives output in the text field. I've used Runtime class to compile the .java file .So how do I get the output from that newly made class file.
Runtime.getRuntime().exec("javac Y://CodeSave.java");
Runtime.getRuntime().exec("java Y://CodeSave.class>output.txt");
In the general case: exec returns a Process instance which has accessors (getOutputStream, etc.) for the I/O streams. You read from / write to those streams.
But: In your code you've used >output.txt. That's a shell feature. If you want to do it that way, you need to spawn a shell, not the java tool directly, and have the shell execute that command line. (A search for spawning/execing a shell should find you lots of examples.)
Using Runtime.exec is definitely not the right way to do it, for various reasons. Examples are that both java and javac rely on environment variables which you can't pass that way.
First of all, I'd ask myself if I really needed to do this. Compiling and executing dynamically created code is a huge security risk.
But if you're sure you need to do it, here's what I'd do.
Move your sources to a dedicated temporary folder
Use the ToolProvider api to compile your sources
Use a dynamic throwaway ClassLoader (ByteBuddy may help you there) with a SecurityManager to load and execute your code from within your application
I want use java code to run some clojure files dynamically which are in some zip files.
If the clj.p1.core.clj is on the class path, it can runs correctly.
require.invoke(Clojure.read("clj.p1.core"));
How to make it dynamically?That is, put clj.p1.core.clj in the a1.zip (maybe some files), the java program could select the zip and then run it?
Probably, you should unzip those files first and then specify a *.clj file when invoking Compile class; take a look at its sources.
What would be much better in your case is to compile a Java class from Clojure sources first and then load that class in Java as well. Just add a specific step into your build process that cares of it. In that case, your Java code will look much simpler and wont' waste time on loading Clojure code dynamically.
Creating a Java file would be easy; just wrap Clojure sources with additional namespace with gen-class declaration. Move its output into your Java project or specify classpath properly. See gen-class page for more examples.
I need to get the file names of each file that is in a particular folder inside my program's JAR while it is running. Is it possible to do this? I'm not sure where to start.
It needs to be done programmatically and be platform independent.
To list the contents of a jar file, simply run:
$jar tf MyJar.jar
Are you looking to do this programmatically from within java?
To do it programmatically, see this example.
You are asking for something that isn't available in general. Classes are loaded via ClassLoader instances, which may get class bytecode from many different places (network, jar file, .class files in a directory, dynamically generated).
The most you can know is the package hierarchy, which you can get from
myObject.getClass().getClassLoader().getPackages()
which returns a list of packages available at the point of invocation. For a given package you probably won't be able to tell where it came from.
When we refer to a class className in jar, how does it know whether it's defined or not when there's no header files(like in c/c++) ?
Java works with classloaders. Classes are needed for compilation, since it will perform static type checking to ensure that you are using the correct signatures of every method.
After compiling them, though, they are not linked like you have in a C/C++ compiler so basically every .class file is standalone. Of course this means that you will have to provide compiled classed used by your program when you are going to execute it. So it's a little bit different from how C and C++ prepare executables. You don't actually have a linking phase at all, it is not needed.
The classloader will dinamically load them by adding them to the runtime base used by the JVM.
Actually there are many classloaders that are used by the JVM that have different permissions and properties, you can also invoke it explicitly to ask for a class to be loaded. What happens can also be a sort of "lazy" loading in which the compiled .class code is loaded just when needed (and this loading process can throw a ClassNotFoundException if the asked class is not inside the classpath)
When you run the Java compiler or your application itself, you can specify a classpath which lists all the jars and directories you're loading classes from. A jar just contains a bunch of class files; these files have enough metadata in them that no extra header files are necessary.
The classes in the jar file contain all the required information (class names, method signatures etc) so header files are not needed.
When you compile multiple classes javac is clever enough to compile dependencies automatically so the system still works.
It looks at the classpath and tries to load the class from there to get its definition.
Java files are compiled into class files which are java bytecode. These class files reside in a file structure where the top level is pointed to by the classpath variable. Compiling in C/C++ creates object files which can be linked into executable binaries. Java only compiles into bytecode files which are pulled in by the JVM at runtime. The following provide more explanation.
http://en.wikipedia.org/wiki/Java_bytecode
http://en.wikipedia.org/wiki/Java_compiler
http://en.wikipedia.org/wiki/Java_Virtual_Machine