Java Dynamic Code Generation with support for generics
Asked Answered
F

4

6

Is there any tool which provides Java dynamic code generation and that also supports generics?

Javassist for example, is the kind of tool that I need, but it does not support generics.

I wrote a small lib which uses the Java 6 Compiler API, however as far as I know it depends on JDK. Is there a way to specify another compiler? Or to ship with my application only the parts that I need to invoke with the Java Compiler API?

Felicio answered 29/8, 2010 at 21:43 Comment(3)
Just out of curiosity: What exactly do you mean with "doesn't support generics" and how is that a problem for you? I'd imagine you could do everything with raw types?Glean
Javassist doesn't support generic types. Therefore I'm unable to compile generic classes. Although I could do the same with objects and casting, for what I'm doing it really is helpful to have generic types at hand.Felicio
If I understand correctly, the type erasure process more or less replaces generics in the source code with objects and casting in the byte code. Generics don't exist at the byte code level.Deuced
R
4

It seems you can manipulate and read generic info with Javaassist. See

http://www.mail-archive.com/[email protected]/msg101222.html

[jboss-user] [Javassist user questions] - Re: Altering Generics Information of Methods using Javassist SimonRinguette Thu, 20 Dec 2007 12:22:14 -0800

I have done further reading on how this is implemented by the compiler and finally found out the answer I was looking for.

You can defenitely do that with javaassist. The key class is javassist.bytecode.SignatureAttribute.

From a CtMethod, i've obtained the methodInfo I add a Signature attribute. You can do it with something like:

CtMethod method = ....
   MethodInfo methodInfo = method.getMethodInfo();
   SignatureAttribute signatureAttribute = new 
SignatureAttribute(methodInfo.getConstPool(),
   "()Ljava/util/List<Ljava/lang/String;>;");
   methodInfo.addAttribute(signatureAttribute);

If your more interesed in reading the signature with the generics inside, you can use the methodInfo.getAttribute(SignatureAttribute.tag).

I hope this helped.

Raymonraymond answered 1/8, 2012 at 11:29 Comment(1)
I have played with this quite a bit and Javassist generated code with generics that works great for JAXB and Jackson serialization. Just need to add the right annotations and generic info for either format. This is particularly useful when nested arrays are to be srialized ass Java completely looses the type info of nested structures like List<List<Long>>. Instead one can emit List<ListOfLong> where ListOfLong isspecial List implementation that has long members.Raymonraymond
F
2

If you are comfortable with writing bytecode then ASM is quite a good library for that kind of thing. That will let you generate a class file on the fly without having to worry about the nitty-gritty of the classfile format. You can then use a classloader to dynamically load it into your application.

Fief answered 30/8, 2010 at 1:21 Comment(0)
G
0

If I recall correctly, it is sufficient to have tools.jar in the classpath in order to use the Java compiler at runtime.

Glean answered 29/8, 2010 at 22:11 Comment(1)
Thanks, I'll run a few tests with this tomorrow and reply back.Felicio
S
0

Actually, javaassist can handle generics using SignatureAttribute.

SignatureAttribute.Type retType = new SignatureAttribute.BaseType(Void.TYPE.getName());
SignatureAttribute.Type[] argType = getArgType();
SignatureAttribute.MethodSignature signature = new SignatureAttribute.MethodSignature(null, argType, retType, null);
method.setGenericSignature(signature.encode());

This project has a lot of very good examples. Hop they are helpful.

Scupper answered 25/7, 2018 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.