Intellij/ Java - identify calls to annotated methods - java

I need to be able to identify calls to methods with specific annotations in Intellij Idea 13, during compile time or by using static code analysis, like calls to #Deprecated methods are identified.
I have looked into doing a structural search in idea, these are supported in static code analysis, and am able to identify method calls from there, but I can't find a way to limit these to calls to method with annotations.
For example
public class A {
#Foo
public void foo(){
// do something...
}
public void bar() {
// do something else....
}
}
public class main {
public static void main(String... args){
A a = new A();
a.foo(); // <---- should be highlighted
a.bar();
}
}

You can by defining your own structural search template like this:
#Foo
$ReturnType$ $Method$($ParameterType$ $Parameter$);
save it e.g. as "methods annotated with #Foo"
and then do a structural search for
$expression$
with the filter reference=methods annotated with #Foo
(to add filter to $Expression$ hover with the mouse over it and then there will be a popup asking you if you want to edit filters and then you add a reference filter)

You could do this in IDEA (which would involve using IDEA's internal interfaces; I don't know offhand which ones give access to annotations).
Depending on your use case, another alternative would be to use an external tool such as the Checker Framework. The advantage is that it is externally supported and has a lot of existing functionality, so there would be less of your own code to write and maintain. Additionally, other people who don't use IDEA would be able to run the analysis. The disadvantage is that there would be less tight integration with the IDE; you would need to configure IDEA to run the analysis, which is straightforward.

Related

IntelliJ and built in Java Function Interface

My Spring components implement java.util.function.Function. The idea behind this is to force a functional style with small encapsulated functions.
#Component
public class MyFunction implements Function<In, Out> {
public Out apply(In in) { .... }
}
// example usage
#RestController
public class MyApi {
private MyFunction f;
public void foo() {
someList.stream()
.map(f)
. // whatever
}
}
Two problems arise with IntelliJ 2018.1:
"Find Usages" offers a choice to find usages of the base method. If I accidentally hit "Yes", IntelliJ finds a zillion usages and slows down until it almost freezes. Well, I should definitely select "No" here, but it is still a small issue.
Using the function in a Stream (e.g. filter) with "Method Reference" (as IntelliJ suggests) is even more problematic. Using "Find Usages" and selecting "No" will not show the "real" usage(s) im looking for. This makes it hard to navigate in the code.
This leads me to my questions: Is it a good practice to use the built-in Function Interface or should I write my own Function without declaring it as a FunctionalInterface? Do you consider the mentioned problems as an IntelliJ bug? Are there workarounds you know of?
Your approach seems valid to me, yet I try to avoid directly implementing Function as much as possible. The main reason is: naming.
I can understand that if a class has a meaningful name (e.g. InOutMapFunction), you might not feel the need for the method to have a meaningful name too. Still, I prefer names like InOutMapper.mapInToOut to InOutMapFunction.apply.
Besides, if you can think of more than one InOutMapper, make it an interface and let the component implement it.
Some may believe it's not worth to create your own functional interfaces if they "correspond" to the existing ones, but I hardly ever regret it, especially that in real uses cases, this impacts readability a lot, e.g. compare:
SomeParticularTypeContextFinder, and
Function<SomeParticularType, SomeParticularTypeContext>.
Here's how I'd implement your example:
#Component
public class PlainInOutMapper implements InOutMapper {
#Override
public Out mapInToOut(In in) { .... }
}
#FunctionalInterface
interface InOutMapper {
Out mapInToOut(In in);
}
// example usage
#RestController
public class MyApi {
private List<In> someList;
private InOutMapper mapper;
public void foo() {
someList.stream()
.map(mapper::mapInToOut)
. // whatever
}
}
You can limit the scope of the search via the 'Find Usages Settings' (default on Windows: CTRL+ALT+SHFT+F7)
The settings apply to the search via ALT+F7 as well as the Mouse Wheel Click one. Maybe limiting it to your current module does the trick?

Intercept all function entry and exit points without third-party components

I have a java program. I would like to intercept every function entries and exits and log them, without changing the existing (~5k) function bodies.
I know AspectJ and Spring AOP are suitable for that. But unfortunately, I am not allowed to use them on the target system (this is not my decistion).
One possibility would be to use following:
void func()
{
logger.logEntry();
// here stuff
logger.logExit();
}
How can I achieve this without any third-party component/tool (this is very important!) without needed to insert these mentioned extra traces? Is there any Java interface/abstract class or any other method/possibility that can be used for this purpose? Or any event handler/subsriber etc.?
As I googled, I found only third-party solutions for this.
What the best soultion would be, if an abstract class with a 2 abstract functions that is called if functions of the from it extended classes' methods are called. Like this:
public abstract class InterceptFunctionCalls
{
// here the internal stuff that call the following methods below
protected abstract void EnteredFunction(String func);
protected abstract void ExitedFunction(String func);
}
Is there any Java interface/abstract class or any other
method/possibility that can be used for this purpose?
No... That's why some third-parties decided to show up and provide for the need. Java as the unextended language isn't trying to offer AOP.

java annotations - automated use at runtime

So I have a question in relation to using custom annotations at runtime.
Let me fill you in on what I am trying to achieve. I have created a custom annotation and applied it to a method in a service class.
public class MyService
{
#MyCustomAnnotation
public String connect()
{
return "hello";
}
}
Now I can go and use reflection to process methods and apply some kind of logic to methods which have my custom annotation applied to them.
for(Method method : obj.getClass().getDeclaredMethods())
{
// Look for #MyCustomAnnotation annotated method
if(method.isAnnotationPresent(MyCustomAnnotation.class))
{
// Do something...
}
}
However, I seem to be missing a piece of the puzzle as I can't figure out how to apply the reflection processing step automatically at runtime.
For example if I have the following main method in my application, how/where do I automatically apply the reflection processing step when I run the following?
public static void main(String[] args)
{
MyService service = new MyService();
service.connect();
}
Obviously this is possible as other frameworks such as spring are able to achieve it but I can't find an example of how they do this.
Credit to #Beri
I used aspects to create a solution.
Reflection is useful if you need to do something at compile time, if you want to do something when the method is called, you should use Aspect Oriented Programming. The most common framework for Java is AspectJ.
I have a multimodule example here. It's an example with scala, but you can omit the scala dependencies and classes and implement it with Java.
If you want to use the aspect in more than one place you must implement it in a separate module in order to include it and avoid repeating logic.

Shall we avoid writing static methods in our java code for better testability?

I was prefer using static methods in my java code, since I think they are "functional""stateless" and has less side-effect. So there may be some helper classes and methods like this:
public class MyHelper {
public static Set<String> array2set(String[] items) { ... }
public static List<String> array2list(String[] items) { ...}
public static String getContentOfUrl(String url) {
// visit the url, and return the content of response
}
}
public class MyApp {
public void doSomething() {
String[] myarray = new String[]{ "aa","bb"};
Set<String> set = MyHelper.array2set(myarray);
String content = MyHelper.getContentOfUrl("http://google.com");
}
}
But my friend says we should avoid defining such static utility methods, since we call them directly in our code, it will be hard to mock them or test them if they have external dependencies. He thinks the code should be:
public class ArrayHelper {
public Set<String> array2set(String[] items) { ... }
public List<String> array2list(String[] items) { ...}
}
public class UrlHelper {
public String getContentOfUrl(String url) {
// visit the url, and return the content of response
}
}
public class MyApp {
private final ArrayHelper arrayHelper;
private final UrlHelper urlHelper;
public MyApp(ArrayHelper arrayHelper, UrlHelper urlHelper) {
this.arrayHelper = arrayHelper;
this.urlHelper = urlHelper;
}
public void doSomething() {
String[] myarray = new String[]{ "aa","bb"};
Set<String> set = arrayHelper.array2set(myarray);
String content = urlHelper.getContentOfUrl("http://google.com");
}
}
In this way, if we want to write unit tests for MyApp, we can just mock the ArrayHelper and UrlHelper and pass them to the constructor of MyApp.
I agree totally about the UrlHelper part of his opinion, since the origin static code make MyApp untestable.
But I have a little confused about the ArrayHelper part, since it doesn't depend on any external resources and the logic will be very simple. Shall we avoid using static methods at this case too?
And when to use static methods? Or just avoid using it as much as possible?
update:
We are using "TDD" in our development, so the testability of a class often is the most important concern for us.
And I just replace the word "functional" with "stateless" in the first sentence since the that's real what I meant.
You'll probably never want to mock a method that converts an array to a list (or set), and this method doesn't need any state and doesn't depend on any environment, so a static method looks fine to me.
Just like the standard Arrays.asList() (which you should probably use).
On the other hand, accessing an external URL is typically the sort of thing that you want to be able to mock easily, because not mocking it would
make the test an integration test
require to have this external URL up every time you run your tests, which you probably can't guarantee
require to have this external URL return exactly what you want it to return in your test (including errors if you want to test the event of an error).
Just beware of one disease very common amongst Java "experts": overengineering.
In your specific example, you either do or don't have a mockability issue. If you had an issue, you wouldn't be asking general questions, therefore I conclude you don't have an issue at the moment.
The general argument is that static methods are simpler and therefore the preferred choice, whenever there is a choice. A would-be instance method must first prove itself of needing to be an instance method.
If this was my project, I would defer any makeovers into instance methods until such a moment where the need for that became clear and present.
Static means you can call the method without instantiating the class. Its good if you want to package your code into a class and you have a function that just does some logic or something basic.
Just don't use a static function to try and edit member variables in the class (obviously).
Personally I think its fine to use the static function, since it is stateless.
Static methods should be used by answering the question "is this method a functionality of a specific instance?".
You shouldn't decide about a static method according to tests, you should do it according to design. Your examples doesn't need an instance because it makes no sense. So static is the better choice. You can always wrap these methods inside specific tester classes to do your tests.
The only situation in which a self-contained functionality is not static is just when you want to provide multiple implementation, so that you are forced to avoid static because you need inheritance.
I often use static methods:
for factory methods (explicitly named constructors)
to provide a functional layer above an object-oriented layer, to compose the objects
and sometimes for general-purpose functions (Apache Commons has many good examples of this)
I never use "singletons" (static objects) and methods that refer to static objects because they are a complete headache to test and reuse. I also avoid hardcoding anything into a static method that could feasibly need to be changed. Sometimes I will provide multiple methods - one with all the dependencies as parameters and others, with fewer parameters, that call the more flexible method with some default (hardcoded) values.
java.lang.Math is static which is a good example. I thought statics are not beeing garbage collected and should be avoided if possible.
No.
As mentioned by Peter Lawrey in the comment for the question, Java is all about object oriented programming. While certain functional aspects are doable and being put into eg. Java 8, at its core Java is not functional. static breaks so much of the benefits of learning how to do modern Java - not to mention all kinds of not-fun-at-all scoping problems - that there's no purpose to use them unless you're some kind of a Java wizard who really knows what happens when you use that magical keyword.
You are not a wizard. Java is not functional. If you want to be a wizard, you can learn. If you want to program in functional fashion, look into hybrid languages such as Scala or Groovy or alternatively explore the fully functional world, eg. Clojure.

How can one add breakpoints or custom code to an interface method implemented by many subclasses?

I am working on source that has a lot of subclasses (call them A and B) implementing a common interface Visitor, with a method visitProgram. Is there any way to break when any of the subclasses hits this method (i.e. A.visitProgram or B.visitProgram)? Alternate language solutions would be fine, but I cannot rewrite the existing source.
Since you're debugging I assume you can add some new code and build the whole thing.
That said, you can use Aspect Oriented Programming (AOP) to get a pointcut that captures the execution of visitProgram, and in theory you can put your breakpoint in the pointcut. You can think of AOP as a technique to cut laterally through your program (as opposed to OOP which builds "vertical" structure).
In this instance, you want to perform something just before each time visitProgram (of any instantiation of your Visitor interface) is run. This is a lateral cut, so AOP should fit your need.
Basically, you'll have a function in which you can set a breakpoint such that any time visitProgram gets called your program will halt just before it executes.
I'd recommend using Spring AOP, it's pretty straight forward, just follow the manual for setup instructions. Your pointcut should look like this:
#Aspect
public class BeforeVisitProgram {
#Before("visitProgram()")
public void doStuff() {
// break in here
}
}
Use an abstract class between the calling code and your implementations, such as:
interface DoesStuff {
void doStuff();
}
abstract class AbstractDoesStuff implements DoesStuff {
void doStuff() {
doStuffToo(); // debug point
}
abstract void doStuffToo();
}
It does mean though that all your implementation must be subclasses of the abstract class, so this approach might not suit every situation.

Categories