For the first time I dealing with Java Annotations. So please pardon me if I m doing anything wrong ! But this class compiled successfully using javac MyFirstAnnotation.java
but when I try to run this source code using java TestMyAnnotation
it throws an error like this
package Annotations;
import java.lang.annotation.*;
import java.util.*;
import java.lang.reflect.*;
#Documented
#Target(ElementType.METHOD)
#Inherited
#Retention(RetentionPolicy.RUNTIME)
public #interface MyFirstAnnotation
{
String author() default "Chiranjib Nandy";
int revisionNumber() default 1;
String date();
}
class MySuperClass
{
public String showMe()
{
return "Do Something";
}
}
class MyAnnotation extends MySuperClass
{
#Override
#MyFirstAnnotation(author="Recmach",revisionNumber=2,date="1st June,2014")
public String showMe()
{
return "Display Something";
}
#Deprecated
#MyFirstAnnotation(revisionNumber=2,date="2nd June,2014")
public void oldMethod()
{
System.out.println("It is a deprecated method");
}
#SuppressWarnings({"unused","deprecation"})
#MyFirstAnnotation(author="Papai",date="1st June,2014")
public void myMethod()
{
int j;
oldMethod();
System.out.println("It is defined in my way");
}
}
class TestMyAnnotation
{
public static void main(String[] args) throws ClassNotFoundException
{
Method myMethods[]=Class.forName("Annotations.MyAnnotation").getDeclaredMethods();
for(Method m : myMethods)
{
Annotation[] annotations=m.getDeclaredAnnotations();
for(Annotation anno : annotations)
{
if(anno instanceof MyFirstAnnotation)
{
MyFirstAnnotation myFirstAnnotation = (MyFirstAnnotation) anno;
System.out.println("name : "+myFirstAnnotation.author());
System.out.println("name : "+myFirstAnnotation.revisionNumber());
System.out.println("name : "+myFirstAnnotation.date());
}
}
}
}
}
Three issues that I fixed.
The public class needs to be TestMyAnnotation.
This line should be MyAnnotation, not what it was before
Method myMethods[]=Class.forName("MyAnnotation").getDeclaredMethods();
The first class at the top should not be public, because you cannot have two public classes inside one file.
Take the following code and put it inside TestMyAnnotation.java. Then run javac TestMyAnnotation.java, followed by java TestMyAnnotation.
import java.lang.annotation.*;
import java.util.*;
import java.lang.reflect.*;
#Documented
#Target(ElementType.METHOD)
#Inherited
#Retention(RetentionPolicy.RUNTIME)
#interface MyFirstAnnotation
{
String author() default "Chiranjib Nandy";
int revisionNumber() default 1;
String date();
}
class MySuperClass
{
public String showMe()
{
return "Do Something";
}
}
class MyAnnotation extends MySuperClass
{
#Override
#MyFirstAnnotation(author="Recmach",revisionNumber=2,date="1st June,2014")
public String showMe()
{
return "Display Something";
}
#Deprecated
#MyFirstAnnotation(revisionNumber=2,date="2nd June,2014")
public void oldMethod()
{
System.out.println("It is a deprecated method");
}
#SuppressWarnings({"unused","deprecation"})
#MyFirstAnnotation(author="Papai",date="1st June,2014")
public void myMethod()
{
int j;
oldMethod();
System.out.println("It is defined in my way");
}
}
public class TestMyAnnotation
{
public static void main(String[] args) throws ClassNotFoundException
{
Method myMethods[]=Class.forName("MyAnnotation").getDeclaredMethods();
for(Method m : myMethods)
{
Annotation[] annotations=m.getDeclaredAnnotations();
for(Annotation anno : annotations)
{
if(anno instanceof MyFirstAnnotation)
{
MyFirstAnnotation myFirstAnnotation = (MyFirstAnnotation) anno;
System.out.println("name : "+myFirstAnnotation.author());
System.out.println("name : "+myFirstAnnotation.revisionNumber());
System.out.println("name : "+myFirstAnnotation.date());
}
}
}
}
}
Hope this link helps.
http://www.shivasoft.in/blog/java/compile-and-run-java-program-in-package-from-command-line/
This is already in stack overflow. You have to compile your class with package like in this post.
try run your Main Java class with adding -cp (classpath) like below commands:
java -cp . TestMyAnnotation
Hope it helps.
Related
I'm reviewing how reflection works or possible work. I have this SomeClassBuilder wherein it has an attribute target : Target with declared annotation TargetAnnotation.
Thing is, is it possible to override/update the values/properties of Target wherein upon invoke of someMethod() would return the parameters on the annotation?
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface TargetAnnotation {
String first();
String second();
// other attributes
}
public class Target {
String first;
String second;
// some other attributes unique only to `Target`
}
public interface TargetHelper {
void setTarget(Target target);
}
public class SomeClassBuilder implements TargetHelper {
#TargetAnnotation(first = "first", second = "second")
private Target target;
#Override public void setTarget(Target target) { this.target = target }
public void someMethod() {
System.out.println(target.first); // should be `first`
System.out.println(target.second); // should be `second`
}
}
Or is it even possible to do it without TargetHelper interface?
Let's say I have this TargetProcessor called before SomeClassBuilder which sole purpose is to fill-in the target : Target annotated with #TargetAnnotation and assign the field/attributes from #TargetAnnotaton to Target.
public class TargetProcessor {
public void parse() {
// look into `#TargetAnnotation`
// map `#TargetAnnotation` properties to `Target`
}
}
You can achieve this by implementing Annotation Processor for your annotation #TargetAnnotation
For further readings and examples:
http://www.baeldung.com/java-annotation-processing-builder
https://github.com/bozaro/example-annotation-processor/blob/master/example-modify/processor/src/main/java/ru/bozaro/processor/HelloProcessor.java
https://deors.wordpress.com/2011/10/08/annotation-processors/
This article explains, how it should be done:
http://hannesdorfmann.com/annotation-processing/annotationprocessing101
Here is my code
import static xdean.jex.util.lang.ExceptionUtil.uncheck;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import xdean.jex.util.reflect.ReflectUtil;
public class Q46765735 {
public static void main(String[] args) {
create(TargetDomain.class).printTarget();
}
public static <T> T create(Class<T> clz) {
T target = uncheck(() -> clz.newInstance());
Stream.of(ReflectUtil.getAllFields(clz, false)).forEach(f -> uncheck(() -> fill(target, f)));
return target;
}
private static <T> void fill(T target, Field field) throws Exception {
TargetAnnotation anno = field.getAnnotation(TargetAnnotation.class);
if (anno == null) {
return;
}
Class<?> type = field.getType();
if (!Target.class.isAssignableFrom(type)) {
return;
}
field.setAccessible(true);
Target value = (Target) field.get(target);
if (value == null) {
value = (Target) type.newInstance();
}
value.setFirst(anno.first());
value.setSecond(anno.second());
field.set(target, value);
}
}
#Retention(RetentionPolicy.RUNTIME)
#java.lang.annotation.Target({ ElementType.FIELD })
#interface TargetAnnotation {
String first();
String second();
}
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
class Target {
String first;
String second;
}
class TargetDomain {
#TargetAnnotation(first = "first", second = "second")
private Target target = new Target("a", "b");
public void printTarget() {
System.out.println(target.first); // should be `first`
System.out.println(target.second); // should be `second`
}
}
Tips:
You can replace lombok by write constructor and getter/setter manually.
ReflectUtil.getAllFields get all fields of the class.
uncheck simply ignore exceptions, you can use try-catch.
I've got an issue with a generic framework I'm writing.
Can someone explain to me, why my code does not compile? I've tried to show it with this simple example. (UPDATED EXAMPLE)
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
public class TestGeneric {
public static void main(String... sss) throws Exception {
Dao dao = new Dao("Hello");
dao.extend();
System.out.println(dao.getHelloWorld());
}
}
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
#interface TestAnnotation {
public Class<? extends AbstractCommand<? extends AbstractDao>>[] commands() default {};
}
abstract class AbstractDao {
public void extend() throws Exception {
for (Field field : this.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(TestAnnotation.class)) {
TestAnnotation annotation = field.getAnnotation(TestAnnotation.class);
for (Class<? extends AbstractCommand<? extends AbstractDao>> commandClass : annotation.commands()) {
AbstractCommand<? extends AbstractDao> command = commandClass.newInstance();
command.doSomething(this);
}
}
}
}
}
class Dao extends AbstractDao {
#TestAnnotation(commands = { Command.class })
private String hello;
private String world;
public Dao(String hello) {
this.hello = hello;
}
public String getHello() {
return this.hello;
}
public void setWorld(String world) {
this.world = world;
}
public String getHelloWorld() {
return this.hello + " " + this.world;
}
}
abstract class AbstractCommand<T extends AbstractDao> {
public abstract void doSomething(T t);
}
class Command extends AbstractCommand<Dao> {
#Override
public void doSomething(Dao t) {
if (t.getHello().equals("Hello")) {
t.setWorld("World");
}
}
}
As soon as I make following changes ...
abstract class AbstractCommand<T extends AbstractDao> {
public abstract void print(AbstractDao t);
}
class Command extends AbstractCommand<Dao> {
#Override
public void doSomething(AbstractDao t) {
Dao dao = (Dao) t;
if (dao.getHello().equals("Hello")) {
dao.setWorld("World");
}
}
}
... everything works fine, but then I have to cast AbstractDao all the time.
As far as I can say, everything should be save, but I keep getting this error.
The method print(capture#3-of ? extends AbstractDao) in the type AbstractCommand is not applicable for the arguments (Dao)
But Dao extends AbstractDao, so where exactly is the problem?
I already found this question generics error: not applicable for the arguments but I'm not sure whether or not it is the same problem I have.
My guess is that it has something to do with 'Because the Java compiler erases all type parameters in generic code, you cannot verify which parameterized type for a generic type is being used at runtime'
Does anyone have a solution for this problem?
Thanks!
You're using an AbstractCommand reference.
Try this
((Command)command).print(new Dao("Hello World"));
I am very new to usage of annotation.
can anyone please tell me how can we declare an annotation and also call all the methods / variables that are declared with that annotation
am using java to implement this annotation
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
#Target(ElementType.FIELD)
public #interface isAnnotatedVariable {
String varName();
}
and used the annotation in
public class Example {
#isAnnotatedVariable(varName = "S")
public String var;
#isAnnotatedVariable(varName = "S")
public String var1;
}
and tried to get the variable names using
public class BuildStepClassDetector {
public static void main(String[] args) throws IOException {
BuildStepClassDetector build = new BuildStepClassDetector();
final Logger4J logger = new Logger4J(build.getClass().getName());
final HashMap<String, Class<?>> isAnnotatedVariables = new HashMap<String, Class<?>>();
final TypeReporter reporter = new TypeReporter() {
#SuppressWarnings("unchecked")
#Override
public Class<? extends Annotation>[] annotations() {
return new Class[] { isAnnotatedVariable.class };
}
#SuppressWarnings("unchecked")
#Override
public void reportTypeAnnotation(Class<? extends Annotation> arg0, String arg1) {
Class<? extends isAnnotatedVariable> isAnnotatedVariableClass;
try {
isAnnotatedVariableClass = (Class<? extends isAnnotatedVariable>) Class.forName(arg1);
isAnnotatedVariables.put(
isAnnotatedVariableClass.getAnnotation(isAnnotatedVariable.class).varName(),
isAnnotatedVariableClass);
} catch (ClassNotFoundException e) {
logger.getStackTraceString(e);
}
}
};
final AnnotationDetector cf = new AnnotationDetector(reporter);
cf.detect();
System.out.println(isAnnotatedVariables.keySet());
}
}
Here is a simple example for declaring annotation and retrieving a annotated field using Reflection.
package asif.hossain;
import java.lang.annotation.*;
import java.lang.reflect.Field;
/**
*
* Created by sadasidha on 21-Aug-14.
*/
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
#interface MyAnnotation {
public String value();
}
class TestClass
{
#MyAnnotation("This is a name field")
public String name;
}
public class Main {
public static void main(String ... args) throws IllegalAccessException {
TestClass testObject = new TestClass();
Field[] fields = testObject.getClass().getFields();
for (Field field : fields)
{
Annotation annotation = field.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation)
{
System.out.println(field.getName());
// get field value
String value = (String)field.get(testObject);
System.out.println("Field Value = "+ value);
//Set field value
field.set(testObject,"Your Name");
System.out.println(testObject.name);
}
}
}
}
You can follow this tutorial http://tutorials.jenkov.com/java-reflection/index.html to learn more about annotation and reflection.
Can I return from method with annotation #Before in AspectJ.
#Before
public void simpleAdvice(JoinPoin joinPoint) {
if (smth == null)
/* return for method, which annotated */
}
If my question is not fully, please ask me another for details.
You can define a method using the #Before , #After , #AfterReturning , #AfterThrowing , #Around . But your class can be registered with the #Aspect .
Also you need to define the pointcut and joinpoints.
For example,
#Before(value="execution(* com.pointel.aop.AopTest.beforeAspect(..))")
public void beforeAdvicing(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println("Name of the method : "+name);
}
#AfterReturning(value="execution(* com.pointel.aop.AopTest.beforeAspect(..))")
public void beforeAdvicing(JoinPoint joinPoint,Object result){
String name = joinPoint.getSignature().getName();
System.out.println("Name of the method : "+name);
System.out.println("Method returned value is : " + result);
}
Your Java class will be,
package com.pointel.aop;
public class AopTest {
public String beforeAspect( ) {
return "I am a AopTest";
}
}
That's it.Hope it helps.
#Aspect
#SuppressAjWarnings({ "adviceDidNotMatch" })
public class TestAspect {
#Around("execution(#Monitor void *..*.* ())")
public void aroundMethodWithMonitorAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.err.println("Around - before a()");
String sessionId = (String) proceedingJoinPoint.getArgs()[0];
if(sessionId != null){
proceedingJoinPoint.proceed();
System.err.println("Around - after a()");
} else {
System.err.println("Around - a() not called");
}
}
public static void main(String[] args) {
new TestAspect().a();
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD })
public #interface Monitor {
}
#Monitor
public void a() {
System.err.println("a()");
}
}
Suppose that I have a .class file, can I get all the methods included in that class ?
Straight from the source: http://java.sun.com/developer/technicalArticles/ALT/Reflection/
Then I modified it to be self contained, not requiring anything from the command line. ;-)
import java.lang.reflect.*;
/**
Compile with this:
C:\Documents and Settings\glow\My Documents\j>javac DumpMethods.java
Run like this, and results follow
C:\Documents and Settings\glow\My Documents\j>java DumpMethods
public void DumpMethods.foo()
public int DumpMethods.bar()
public java.lang.String DumpMethods.baz()
public static void DumpMethods.main(java.lang.String[])
*/
public class DumpMethods {
public void foo() { }
public int bar() { return 12; }
public String baz() { return ""; }
public static void main(String args[]) {
try {
Class thisClass = DumpMethods.class;
Method[] methods = thisClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i].toString());
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
To know about all methods use this statement in console:
javap -cp jar-file.jar packagename.classname
or
javap class-file.class packagename.classname
or for example:
javap java.lang.StringBuffer
You can use the Reflection API
package tPoint;
import java.io.File;
import java.lang.reflect.Method;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class ReadClasses {
public static void main(String[] args) {
try {
Class c = Class.forName("tPoint" + ".Sample");
Object obj = c.newInstance();
Document doc =
DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new File("src/datasource.xml"));
Method[] m = c.getDeclaredMethods();
for (Method e : m) {
String mName = e.getName();
if (mName.startsWith("set")) {
System.out.println(mName);
e.invoke(obj, new
String(doc.getElementsByTagName(mName).item(0).getTextContent()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}