i have an idea and want to know, if it is possible or not and if yes, how. I´m working on a library for other users to simplify their life's.
I have two annotations.
Darwin:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Darwin {}
DarwinVersion:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DarwinVersion {}
And one aspect.
DarwinAspect:
public privileged aspect DarwinAspect {
private final static Logger LOGGER = LoggerFactory.getLogger(DarwinAspect.class);
after(): execution((@bla.Darwin *).new(..)) {
int numberOfDarwinVersionFields = 0;
LOGGER.debug("Try to add version!");
try {
Field darwinVersionField = null;
for (Field field : thisJoinPoint.getTarget().getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(DarwinVersion.class)) {
numberOfDarwinVersionFields++;
LOGGER.debug("DarwinVersion found on field " + field + "!");
darwinVersionField = field;
}
}
if (numberOfDarwinVersionFields > 1) {
LOGGER.error("To many @DarwinVersion annotations in class " + thisJoinPoint.getTarget().getClass() + "!");
} else if (numberOfDarwinVersionFields == 0) {
LOGGER.error("No DarwinVersion field found in class " + thisJoinPoint.getTarget().getClass() + "!");
} else if (darwinVersionField != null) {
LOGGER.debug("Set DarwinVersion on field " + darwinVersionField + "!");
darwinVersionField.setAccessible(true);
darwinVersionField.set(thisJoinPoint.getTarget(), VersionProvider.getVersion(thisJoinPoint.getTarget().getClass()));
}
} catch (IllegalAccessException e) {
LOGGER.error(e.getLocalizedMessage());
}
}
}
(This code will set a DarwinVersion automatically to every object after the constructor was called.)
The idea is to weave any classes of users, who declare their classes with the annotations. They only should add my library to their classpath. Like in this example:
@Darwin
public class Example {
@DarwinVersion
private Long version;
public static void main(String[] args) {
Example example = new Example();
System.out.println(example);
}
@Override
public String toString() {
return "Example{" + "version=" + version + '}';
}
}
This code is working, but only in my own project. In a testproject, which includes the Darwin-library and is annotating a testclass, the annotation is ignored and no code will be weaved. Is is it possible with load time weaving?