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?

halfwarp
  • 1,780
  • 5
  • 24
  • 41
  • 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? – meriton Aug 29 '10 at 22:12
  • 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. – halfwarp Aug 29 '10 at 22:45
  • 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. – emory Aug 29 '10 at 22:51

4 Answers4

4

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

http://www.mail-archive.com/jboss-user@lists.jboss.org/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.

Kiril
  • 1,028
  • 1
  • 9
  • 23
  • 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>. Instead one can emit List where ListOfLong isspecial List implementation that has long members. – Kiril Sep 28 '12 at 20:46
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.

Richard Warburton
  • 1,462
  • 1
  • 9
  • 13
0

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

meriton
  • 68,356
  • 14
  • 108
  • 175
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.

debugging
  • 53
  • 8