The Artima Developer Community
Sponsored Link

Java Community News
Annotation Transformers in Java

4 replies on 1 page. Most recent reply: Jul 13, 2014 3:22 AM by kishan sanapala

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
    Next Topic
Flat View: This topic has 4 replies on 1 page
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Annotation Transformers in Java Posted: Oct 23, 2006 12:26 PM
Reply to this message Reply
Summary
While annotations are a convenient way to specify configuration data for Java applications, annotations lack the flexibility of an external configuration file, including the ability to override configuration values without having to recompile source code. In a recent blog post, Cedric Beust describes a method to transform annotations at runtime.
Advertisement

The debate whether to specify configuration information in the form of annotations on Java source code or in external configuration files, is still ongoing. The current consensus seems to be that configuration that impacts the source code—such as marking a method as @Test—should use annotations, whereas an external file is more suitable for configuration info that impacts the behavior of an application.

While an external configuration file can be changed—and subsequently reloaded by the application—without altering the source code, configuration specified as an annotation can only change by recompiling the source.

In a recent blog post, Annotation Transformers in Java, TestNG author Cedric Beust discusses various approaches to overriding annotations via XML, including:

[An] approach that blends these two techniques has also been under scrutiny recently: being able to override Java annotations with XML files. I haven't come across an implementation of this idea that can claim it's the defacto standard, and at this point, I suspect that this approach is unlikely to take off because it suffers from the "worst of both worlds" syndrome. Here is why. Consider the simple following code:

public class Mytest {  

@Test(invocationCount = 10)    
public void verify() {    // ...  }}

This instructs TestNG to invoke the verify() test method ten times. If I want to override this value at runtime, I find myself having to write a fairly complex piece of XML code in order to pinpoint the exact annotation I'm trying to override. It would probably look like this:

<override-annotation>
  <package name="org.foo.tests">
    <class name="MyClass">
      <method name="verify">
        <annotation name="org.testng.Test">
          <attribute name="invocationCount" value="15" />
        </annotation>
      </method>
    </class>
  </package>
</override-annotation>

I have been working on a slightly different approach with TestNG that lets you specify this runtime override in Java. Again, it's not a silver bullet and suffers from some of the compromises expressed above, but if you can live with the idea that you have to recompile your override if you modify it (but not the annotated code you are trying to override, so it's already a progress), it's actually fairly simple to achieve.

Beust introduces the notion of an annotation transformer interface:

public interface IAnnotationTransformer {  

    public void transform(ITest annotation, 
        Class testClass,
        Constructor testConstructor, 
        Method testMethod);
}

An implementation of this interface serves as the mechanism to transform the meaning of a specified annotation:

public class MyTransformer implements IAnnotationTransformer {  
    public void transform(ITest annotation, 
                          Class testClass,                        
                          Constructor testConstructor,         
                          Method testMethod)  {    
        if ("verify".equals(testMethod.getName())) {          
            annotation.setInvocationCount(15);    
        }  
    }
}

Overriding an annotation then does not require recompiling source code of the class that contains the specified annotation. Beust implemented annotation transformers in the upcoming 5.3 release of TestNG. Of this approach, he observes that:

The advantage of annotation transformers is that they can be very powerful: it's very easy to apply them to several methods, several classes, all methods of a class or of a package.

However, he also notes that implementation can be tricky, since, for instance, the current version of the JDK does not provide write access to annotations.

What guidelines do you follow in your projects to decide between annotations and an external configuration file? What do you think of Beust's approach to overriding annotation values?


Gregg Wonderly

Posts: 317
Nickname: greggwon
Registered: Apr, 2003

Re: Annotation Transformers in Java Posted: Oct 24, 2006 9:21 PM
Reply to this message Reply
I've started using the Jini ConfigurationFile class for my choice of configuration because it allows me to use live code for configuration values.

The following would be used for your example.

org.foo.mytests.MyClass {
invocationCount = 15;
}

pretty simple and direct.

Javid Jamae

Posts: 16
Nickname: javidjamae
Registered: Jan, 2003

Re: Annotation Transformers in Java Posted: Nov 18, 2006 5:15 PM
Reply to this message Reply
> The current consensus seems to be that configuration that
> impacts the source code—such as marking a method as
> <code>@Test</code>—should use annotations, whereas an
> n external file is more suitable for configuration info
> that impacts the behavior of an application.
>
> While an external configuration file can be changed—and
> subsequently reloaded by the application—without altering
> the source code, configuration specified as an annotation
> can only change by recompiling the source.

I think what really needs to be considered here is whether a configuration change could break behavior or not. If not, then you can feel comfortable applying the change while the system is running in production and external config files are the best place for the metadata. If a metadata change could break behavior then you'll want to test the change by going through a full release cycle (change code, build, test, deploy).

If you're going to go through a full release cycle then the whole "you don't have to recompile" argument is irrelevant. There is no benefit to not recompiling besides the 5-10 seconds of time savings, which is not worth the tradeoff of having more complex metadata.

For example, Hibernate mappings are often in XML, but annotations provide much simpler configuration. You're not going to change your mappings dynamically at runtime are you? Any changes you make to your mappings (whether in XML or annotations) could potentially be behavior breaking. So annotations seem like a much better choice from my perspective.

sathya b

Posts: 1
Nickname: sathya3
Registered: Jun, 2010

Re: Annotation Transformers in Java Posted: Jun 8, 2010 4:25 AM
Reply to this message Reply
My method verify1() is being called 3 times and not 5 times although i am using [annotation.setInvocationCount(5);]
I call the testng file (SimpleTest) using a Suite.xml file

Please help not sure where i am going wrong.Also when does the method "transform" get called


import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.TestNG;
import org.testng.annotations.Test;
import org.testng.internal.annotations.ITest;

public class SimpleTest implements IAnnotationTransformer {

public void transform(ITest annotation, Class testClass,
Constructor testConstructor, Method testMethod)
{

if ("verify1".equals(testMethod.getName()))
{
annotation.setInvocationCount(5);
}
}// end of method transform()

@Test(invocationCount=3)
public void verify1()
{
SimpleTest s = new SimpleTest();

System.out.println("Fast test");

}

}

Thanks in Advance
Sathya

kishan sanapala

Posts: 1
Nickname: kishans
Registered: Jul, 2014

Re: Annotation Transformers in Java Posted: Jul 13, 2014 3:22 AM
Reply to this message Reply
Hi i am also facing the same issue.. can anyone guide me in Transform annotation?

Flat View: This topic has 4 replies on 1 page
    Next Topic Topic: Writing DSLs with Scala Parser Combinators

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use