I have started porting my server side C# app to Java. One of the things it does is dynamic generation of code using the CodeDOM framework, compiling it to bytecode, and loading the class during runtime. There are also scenarios where we have used Expression Tree for lightweight dynamic generation of methods.
I did some research and I believe the closest I came is Javaassist. I would appreciate if there are any other frameworks that supports dynamic code generation and compilation. I am a fresh recruit in the Java world.
There's the Java Compilation API (for example, http://www.accordess.com/wpblog/an-overview-of-java-compilation-api-jsr-199/).
If you just need to evaluate expressions, consider any EL, like OGNL or MVEL.
Groovy, JRuby, and Scala are the most mainstream dynamic languages that allow a huge range of options, from simple expression evaluation to full-blown Java interaction.
To modify classes, you can use javaassit, asm, cglib(actually, it depends on asm), bcel, and etc.
Among them, I recommend asm, because of its better lightweight and better performance.
Using asm, you can generate some classes dynamically. But if you want to modify the classes, which are running in the jvm, you have to use Java Instrument API to retransform the existed classes.
You can see this paper for more info. http://www.cs.helsinki.fi/u/pohjalai/k05/okk/seminar/Aarniala-instrumenting.pdf
More doc about Instrument from oracle.
http://docs.oracle.com/javase/6/docs/technotes/guides/instrumentation/index.html
I have successfully used Janino for dynamic code generation. Like Javassist, it can compile Java source code in-memory. Also like Javassist, it lacks Java 1.5 language features, but apart from that it is easy to use.
The SimpleCompiler class is a good starting point.
I would look at lisp (or other dynamic languages) that have been targeted to jvm.
wiki article
Related
Just wondering if there are any Java implementations that work without a JVM. The reason I'm interested is, well, simply because I'm curious, and I was wondering if there were any "lightweight" Java implementations (without all the Sun libs attached).
I'm also interested in embedding Java in C++, but embedding the JVM in C++ seems rather ridiculous to me. I just want to exploit some of the Java language features in my C++ apps, but not exploit all the frivolous Java APIs.
EDIT:
I see from a lot of the answers I've gotten that I need to clarify...
I recently got in to developing node.js applications, which uses JavaScript. JavaScript in istelf is a language spec, it doesn't automatically come with the DOM, window.open, etc., although it did for a while. I'm wondering if there's something similar to Google's v8, except not for JavaScript, but for Java. In the end, I don't care if I can't write Hello World apps with it, I just want to be able to embed Java in a C++ application the way I can embed JavaScript in a C++ application with v8 or SpiderMonkey. If I could do that, then I could implement console output in C/C++ and then make that implementation callable from Java.
Do you want the Java VM alone without the API(STandard Library) ?
The JRE is composed by the JVM (Virtual MAchine) and the Standard Library, I have doubt that you can find a java implementation without the JVM ... You could find a compiler that compile java source code into native code(take a look at GCJ), but not a Java implementation without the VM.
Take a look at this wikipedia page to see some alternative Java implementations .
There's GCJ (GNU Compiler for Java), but the project has been deprecated since OpenJDK was open sourced.
there are light weight java processors designed for use in small devices for example JOP
As others have hinted, the "JVM" is the mechanism that knows how to load classes, interpret "bytecodes", and manage storage. It does not inherently include any of the java.lang... stuff, except that a few classes (String, Class, et al) are needed to represent classes and other basic data structures in the JVM.
As a result, Java without a JVM is just a bunch of meaningless bits.
There are (or were) compiled versions of Java that do/did not need the interpreter (though a reasonably compact interpreter is quite easy to build). A primitive class loader and some sort of storage management are still necessary, but class loading can be kept simple and for short-lived apps (or those that live with special restrictions) the storage manager need not do garbage collection.
As pstanton suggests, there are "lightweight" Java (or "Java-like") implementations that are suited for small devices.
IMHO, You need to re-exampine what it is you really want.
Java runtime consists of two main components
The JVM to run the code
The standard libraries which come with it.
You suggest you want to use Java, but you don't really have anything left without these.
For example, you cannot even write a "hello world" program without the libraries as String is a class in the JDK.
I have a need for providing code snippets at runtime.
For this to work well, I basically need to call into the scripting language, and back into Java. For this to be usable in a debug scenario StackTraces must be usable too (so methods and linenumbers go directly to the script source like in modern JSP-pages) and Exceptions must bubble up correctly.
What scripting languages - where the source is read at runtime - can provide this? JSR-223 support is a bonus.
I think JRuby is best choice because:
Its performance as a scripting language is good.
It can execute in two mode (Compiled, Interpreted).
It supports Ruby on Rails and you can use JRuby for Rails applications in production environments.
You can invoke the classes of the Java Platform easily without any restriction.
I think Groovy would be the perfect fit in your case given it's super similarity and ease of integration with Java not to mention that it's pretty much the most mature JVM language out there with excellent support from the likes of SpringSource.
As an example of JSR support, Groovy has it.
I'm interested in metaprogramming (i.e. programs that help programmers do tedious programming tasks). I'm looking for a tool which has the following properties:
usable both at compile time and runtime;
inspects program structure;
can add new classes, methods or fields and make them visible to Java compiler;
can change behavior of methods;
Java-based (well, Java is most popular programming language according to some rankings);
good integration with IDEs and build tools like Ant, Gradle or Maven;
actively maintained project;
easy to use and extend;
There are some solutions for this, like:
reflection
AspectJ
Annotation Processing Tool
bytecode manipulation (CGLIB, Javassist, java.lang.instrument)
Eclipse JDT
Project Lombok
Groovy, JRuby, Scala
But unfortunately none of them meets all the criteria above. Is there any complete metaprogramming solution for Java?
There's JackPot, which is Java based but I don't think gets a lot a current attention. Has ASTs and symbol tables AFAIK. You can probably extend it; I doubt anybody will stop (or help) you.
There's the Java-based compiler APIs for the Sun, er, Oracle java compiler. They're likely actively maintained, but I don't think you can modify source code and regenerate it. Certainly has symbol tables; dunno about trees. Probably pretty hard to extend; you have to keep up with the compiler guys, not the other way round.
There is ANTLR, which has a Java implementation and a Java parser that will build ASTs. I don't think it has full symbol tables, so doing serious code analysis/revision is likely to be hard. ANTLR is certainly actively maintained, and nobody will object to you enhancing the Java grammar with symbol tables. Just know that will take you about 6 months for Java 1.6 if that's all you do. (That's how long it took our internal [smart] guy to do it for DMS, starting with symbol table support for 1.4).
Not in Java, and not easily integrated into IDEs, but capable of carrying massive analysis and transformation on Java code is our DMS Software Reengineering Toolkit with its Java Front End.
DMS is generic compiler machinery: parsing, AST building, symbol table machinery, flow analysis machinery, with that additional bonuses of source-to-source transformations and generic prettyprinting of ASTs back to legal text including retention of comments. It offers a set of APIs supporting these services, and additional tools for defining grammars and langauge-dependent flow analyzers.
The Java Front End gives crucial detail (using those APIs) to DMS to allow it process Java: a grammar/parser, full symbol table construction for Java 1.4-1.6 (with 1.7 due momentarily), as well as some control and data flow analysis (to be extended over time because this stuff is so useful).
By using the services provided by DMS and the Java Front end, one can reasonably contemplate building arbitrary Java anlaysis and transformation tools. (This makes the tool a "complete" metaprogramming tool, in that it can inspect any language structure, or change any language structure, as opposed to say template metaprogramming or reflection). We believe this to be much more effective than ad hoc tools because you don't have to build the infrastructure, the infrastructure provided is robust and handles cases you don't have the energy to implement, and it is designed to support such tasks. YMMV.
DMS/Java Front end have been used to construct a variety of Java tools: test coverage, profilers, dead code elimination, clone detection on scale, JavaDoc with hyperlinked source-code, fast XML parser/generators, etc.
Yes, its actively maintained; undergoing continuous enhancement since the first version in 1998.
There's a Java metaprogramming framework that is part of Tapestry IOC, it's called Plastic. It munges class bytecodes using custom classloaders, I haven't tried it yet but it looks like it gives a simple interface that still enables the programmer to make powerful metaprogramming changes.
Check out the Meta Programming System:
http://www.jetbrains.com/mps/
It has great IDE support and is used quite frequently by the smart folks at JetBrains.
Check out Spring Roo.
I need to call some javascript code from my java app, can I do such a thing?
thanks
adi
You can do this using a third-party library like Rhino, but there is no straightforward way to invoke JavaScript code from Java. Though the two have similar names, they have about as much in common as a car and a caramel.
More generally, having programs written in one language interact with languages written in another is often tricky due to the internals of the two programming language implementations not being compatible with another. There are many exceptions to this rule and a lot of effort has been invested in making projects work in multiple languages, but there's often a high startup cost.
Yes, you can, either by grabbing Rhino from Mozilla and using its integration libraries or by using the JDK 1.6 "ScriptEngine" facility.
The version of Rhino (the Mozilla-authored Java-implemented JavaScript engine) included with JDK 6 is pretty old and buggy, be warned.
LiveConnect does this nicely, see the references and examples for JSObject. You'll probably be interested in JSObject.eval, which will give you the ability to execute JavaScript code under the context of any JavaScript object.
I am about to start developing a small Java desktop app. The app is just an engine for which the user provides Java classes to do the work (translating input to output).
I would like the user to provide actual Java classes as files that can be loaded (and reloaded) on the fly.
For this particular use, is there any reason why Java would be more cumbersome than Groovy or Beanshell? I'm not asking for a comparison of Groovy/Beanshell and Java as there are many. Rather, I want to know if it's easier to dynamically load Groovy or Beanshell classes from files compared to Java.
For Java 1.6, is the JavaCompiler the best way to dynamically load code? I would like to use all language features so I think Janino is out. Also, any problems with reloading?
Note: I have seen this and this, but I'm not sure they answer my question.
JavaCompiler is very versatile, but it entails a minor, potential configuration problem: In javax.tools, ToolProvider.getSystemJavaCompiler() identifies the compiler's class as com.sun.tools.javac.api.JavacTool. On some platforms, that class is not part of the JRE; a JDK appears to be required. Here is an example.
Also consider javax.script, discussed here. Several scripting engines are supported.