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.
Related
Is there a way to build a project into a namespace, say "org.example.this.particular.library" without actually creating that directory structure in the source tree? In other words, I want to put my files in "[project]/src/" rather than "[project]/org/example/this/particular/library/".
EDIT: The library contains multiple files, so the compiler needs to know where to look to resolve other package classes.
You can if you compile this file explicitly or use the Compiler API to compile your files.
Either way it if far more complicated than just using those directories.
If you use an IDE and a build tool you don't really need to care what the directories are.
I would like to know if there is a way to edit the codes in a class file? Because I dont seem to be able to compile a java file into a class file with the use of cmd as it will always detect errors . The Jar file that I am using already have its own existing class files and I would like to update one of the the .class file with a few lines of codes. But when I copied the codes from the class file and put it into a java file together with my added lines of codes, and then try compiling it using cmd, the cmd will generate error whenever I tried to compile it to generate the class file.
Does that mean that I will need to de-compile the whole jar file and make it into a java file and then recompile it into a class file then make it into a new jar file again,? In order to achieve what I am trying to do?
Right now I am using this JCIFS jar file and I would like to add in some lines of codes into one of the class file. I am refering to this "https://code.google.com/p/android-smb-streaming/" as a guide and I discovered that this person is able to customize / add a new class file with the same lines of codes from the existing class in the jar file together with his own added lines of codes.
May I know how do I achieve this? Thank you.
What you have to do here is a common situation: you found a bug/feature request for an open source project.
Instead of hacking it you could try to contact the author of the library, submit your contribution and wait until it gets a new release so it has your new cool feature.
On the other hand, you can use the exposed API to customize it for your needs, e.g., create a specific subclass that overrides the required method containing that few lines of code and use the API in a way that it uses your implementation.
If you want to go the hacky way, there's no need to manipulate the classfiles directly (it is far more complicated): the easy way is to download the project, read the docs how to set it up (so you can compile it with cmd w/o errors), add your patch, compile it, then you can update the used JAR file with the new class file (or files: note that there might be multiple files generated if you're using inner classes or lambdas). Just don't forget to mention that somewhere in the docs, because otherwise no one will ever know that the library is slightly modified...
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.
We have an java application in which the user can write/execute their own java code and use imports from compiled jars - i.e. they write it, and it is compiled and run by the application. They can also save this code (along with various other information that they are using) - currently this is saved to a human-readable xml file.
I want to be able to use those save xml files in an IDE (principally, Intellij), so that if the user changes things in their compiled jar in the IDE, these changes can also be picked up in the save xml file.
For example, if a save file used a class from the compiled jar, it may have the following import:
import com.company.project.package.subpackage.MyClass;
Let's say that class was moved, so the import was:
import com.company.project.package.subpackage.subsub.MyClass;
...this would change all the save xml files that used that class and import - just as the IDE would for all the other usages in the compiled project.
(This, and other examples, arises because the compiled jar is both constantly in development and in use using the aforementioned application.)
At the moment, if I were to add the save xml files to a sub-project in the IDE, the user can edit the save files manually, possibly taking advantage of 'find/replace' or 'search for usage in text' functions. This is better than nothing, but still a rather involved/complicated process. Also, there is no checking that the code in the save files are consistent with the code in the compiled project.
One approach that I am considering is a script or a test class that would unpack the save xml file, writing the java code to java files, and then try and compile (and possibly running/testing) those java files.
A further step would be to write a maven plugin (we use maven for our build cycle) or an ant script (ant still has its uses...) to do this, and possibly make this part of our build process - i.e. you cannot compile the project without ensuring all of the save xml files in its sub-project also compile.
Does this seem like a reasonable approach?
Are there alternative approaches that anyone could suggest?
..saving as a .java file is not the solution I'm looking for.
Save it as a Zip with 1 (or more) XML files as well as any source (in paths according to package) that is required. You could even include other files easily, a manifest, help files etc.
This has a number of advantages:
It allows source & include files to be a different encoding to the XML
It consolidates all the necessary parts of the project into one file, without any 'jumping though hoops' to make one format fit inside another.
It allows different compression levels as appropriate to the data (e.g. text/XML compresses well, whereas a serialized image does not).
I need to create runnable .jar file programmatically from a string. My decision is to create a .class file from string and add it to the .jar using JarOutputStream.
What API must I use to create the .class file?
Are there any other solutions to create a .jar from the source code?
In order to do that, you can use the Java Compiler API.
There is this excellent tutorial that can walk you through.
To compile code, you need a compiler. You can either use the SunOracle compiler or the Eclipse compiler. Calling the compiler API (both have documented APIs) will produce a .class file in a temporary location. You can then make a jar.
For an example of this sort of thing, start with, for example, the Maven Compiler Plugin, which is a Java module which uses the compiler API. You'll have to find your way into the Plexus compiler module.