Design a custom annotation to invoke a method in a jar - java

I'm a bit new to annotations in Java. Is it possible to design a custom annotation which when used in a class automatically invokes a method present inside another Class. TIA.

The answer is "sort of": annotations by themselves do nothing (except "compile time" annotations that affect the compile process).
Meaning: just attaching an annotation to something doesn't magically cause a method to be called at some arbitrary point in time.
This works differently: you have some sort of framework - and at some point you ask the framework to process an object, class, ... And then the framework might check for the presence of certain annotations to "do" something based on that check.
Thus: it is possible to implement custom annotations, and it is also possible to make some "framework" react to the presence of that annotation.
In case you find this answer too generic - well, it can't be more precise/specific than the question ...

Related

Is there a way to annotate the INSTANCE field of kotlin objects?

I have a Kotlin object that has several fields exposed as static #JvmFields. The parser that I use (which I cannot edit or change) looks for public static fields and creates a configuration file based on those. Since the INSTANCE field is public too, the parser generates a new category called instance. Is there a way to add actual annotations to the INSTANCE field? I would want to add the #Ingore annotation to it so the parser does not use the INSTANCE field.
Basically, the answer is no, Kotlin does not allow annotating or altering the INSTANCE fields in any other way. If you believe this could be a useful feature, please file a feature request at kotl.in/issue.
The valid solutions to this problem are:
Make the bytecode analyzing tool Kotlin-aware, i.e. make it behave correctly with Kotlin declarations. Though this requires non-trivial job to be done and does not seem possible in your case, it could be a valuable time investment.
Create another ad-hoc tool that post-processes the classes produced by the Kotlin compiler and adds the annotations you need, then include that tool into your build.

How to understand annotation in java And How to implement my annotation in java?

What I have known are:
annotation was added in java 5
annotation can be using in method, class, and property
annotation can work in RUNTIME, CLASS, SOURCE( I don't know how to work with CLASS and SOURCE, and their's features)
annotation with retention which is RUNTIME can be implement when java program is running.
And I want to implement a annotation to have follows features:
ensure class only being allowed to create a instance
ensure methods only being allowed to access method in the class
it is like as friend in c++
it is same as public and private , but more dynamicall, like
#MyAnnotation(allowMethods={xxx.doSomething})
public void getValue(){}
the getValues method only can be accessed in the instance self and xxx.doSomething() method
What should I do and learn in next?
And Where can I learn about these?
I think you might be misunderstanding something there. Annotations are descriptive elements, not parts of your program. You can write as many annotations as you want, and people who use your code will still be able to ignore them.
That said, an annotation that enforces a policy (as yours does) can actually be implemented, either at compile or at runtime, but you need an external mechanism to help you. I can think of 3:
Annotation processing lets you interact with the compiler and process annotations by generating code or by omitting compiler errors. Unfortunately, I don't think it will work for your case, as you want to protect your annotated type from instantiation, and that means the call site doesn't actually have an annotation. Annotation processing only gives you access to the actual code pieces that have annotations, not to those that refer to them.
AspectJ allows you to write policy enforcement aspects and omit compiler errors, based on static pointcuts. The problem here is that static pointcuts have very limited semantics, so while you could forbid the instantiation of your class altogether, or from certain packages, you could not limit the your class instantiations to 1.
The third way, and probably the only sane way is that you use a container like Spring or Guice and configure your class as singleton. As long as you only retrieve your class from the container, it will never create a second instance.
Finally: If you want to limit the number of instantiations of your class, you can always use a classic Singleton pattern approach.

How should I write my own custom Annotation in Java

Let say I want to check condition[let say boundary values] on some of the method arguments.Instead of writing "if" condition to check [boundary condition] on every method, I want to annotate argument only. Let me know the Steps to understand it. Working code will be awesome.
You need to look into method interception. What you are wanting is an interceptor that can validate method arguments on invocation. I like the AOP Alliance interfaces for this, they work pretty well. It also integrates with Guice natively and I think Spring has support for it as well.
Steps:
Define an annotation
Create an interceptor to process the annotation
Bind the interceptor (manually or using some framework)

Force a class to implement one of two interfaces that implements another interface

I am not really sure about Java Annotations, but I think they can solve my problem.
I have an java interface "Target". This is an empty interface, so I can give that implementation into an "TargetHolder", which is simply a list of Targets.
Now I only have 2 Types of Targets. Type "Alpha" and type "Beta".
Type "Alpha" has no functionality in common with Type "Beta".
Easiest way would be to just extend "Beta" and "Alpha" from "Target". But with this solution it is possible for a programmer to create a class that extends "Target" only, which must not be possible.
Can I solve that with annotations?
How?
In theory you might be able to implement the checks (at compile time) using an annotation processor. The problem is that javac will only run an annotation processor on a source file if it finds the right kind annotation in the source.
"After scanning the source files and classes on the command line to determine what annotations are present, the compiler queries the processors to determine what annotations they process. When a match is found, the processor will be invoked."
(Javac manual)
But it seems like you want an annotation on an interface to constrain all classes that implement that interface. That means checking all such classes ... but I can't see how you could trigger the running of an annotation processor on a class that has no relevant annotations.
That leaves you with a couple of options:
Implement the checking as (say) a PMD rule.
Write a tool to find the relevant interfaces at runtime, retrieve their annotations, then trawl for all classes that implement the annotated interfaces.
My advice would be to put this into the "too hard" basket. It is probably going to take more time to implement this than you would save in picking up related coding errors earlier. (I'm thinking that the case that you are trying to avoid will be picked up when someone tries to use class. So, you (or your client) should find your (their) incorrect class in testing ...)
How about?
Create a package just for this work. Let us call it target.
Put Target.java in package target - package private.
Put Alpha.java in package target - public
Put Beta.java in package target - public
Compile, jar, and seal package target.
Using Tool like JArchitect allows to enforce design rules.
In your case you can use the following cqlinq query:
warnif count > 0 from t in Types where t.Implement ("Target")
&& (!t.Implement("Alpha")|| !t.Implement("Beta"))
select t

Check if the method is invoked

I am trying to create a logging OSGi bundle, which would be able to log input, output, exception (if any) parameters of all the methods which are marked with specific annotation.
I have tried to set up the Spring AOP logging in OSGi but I was unsuccessful.
All I need to know is how to determine when the method is being called? For example I have scanned all methods in a class which are annotated with my annotation and I have those methods in array or list.
For example there are three methods: getStatus, getDetails, getSomething. And the user invokes getDetails method, so how should I know when this method is invoked?
Detecting method calls requires you to instrument your code. If you want to do this at runtime this requires byte-code manipulation (which is what Spring AOP does, as far as I know). Alternatively you could instrument your code at compile-time using a custom preprocessing step that generates the instrumented Java-code, but I don't know if that is much easier.
I guess your best bet is to try and Spring AOP working.

Categories

Resources