What is Concrete Call and how is it different from Reflection? - java

I was studying about the Dagger 2 - dependency injection library for Android - and in many articles, when the autor compares the Dagger 2 with it's older version ( Dagger ), He says this:
(...)
The new release, as promised, addresses many of the problems of the original:
No more reflection — everything is done as concrete calls (ProGuard works with no configuration at all)
(...)
From: https://blog.gouline.net/dagger-2-even-sharper-less-square-b52101863542#.w33tjdttt
I know that Reflection can be used for observing and modifying program execution at runtime, but what about these Concrete Calls? What are them and how they are different from Reflection?
Obs.: Would be great if anyone could provide some sample code/ use case about how to create/ use these Concrete Calls.

Well...Dagger used some reflection and dagger 2...doesn't.
Dagger 2 uses annotation processing to generate code at compile time. All those annotations you put on your classes, #Component, #Module, and so on, signal to the dagger 2 compiler what to do.
It will use them to create a dependency graph, validate it, and then create the code. There are some benefits to this approach, compared to dagger:
Compile time validation (if you have dependency cycles, or can't provide something, it won't compile and you get an error at compile time, and not an exception when running your program)
Performance (everyting is just simple java—no reflection involved)
Proguard 'support' (by not relying on reflection, there will be no issues with proguard)
So, as already mentioned in the comments, concrete calls in this context would mean the elimination of reflection and generating code. Dagger 2 will produce a whole lot of source files, with which you can also easily debug your code.

Concrete calls are where you call the method directly, and the compiler creates a call instruction:
System.currentTimeMillis();
This is is the fastest way to call a method, but it only works if you know at compile-time which method you need to call (which is 99% of the time the case). This is how you write code normally.
Sometimes, you don't know what method you need to call. Maybe a user or a file tells you which method you need to call. For this, you need to use reflection. This is much slower, but allows you to dynamically indicate which method to call:
Scanner in = new Scanner(System.in);
String method = in.next();
// Reflection invocation:
Object result = System.class.getMethod(method).invoke();
System.out.println("Result was: " + result);
This would allow you to type currentTimeMillis into the command line, and return the value. You could also type nanoTime and it would print the result of that too.
Because reflection is an extra layer of indirection (there is no System.currentTimeMillis() call in the reflection code above - but it could call it!), tools which operate by scanning through the compiled code and rewriting method calls will fail to properly handle reflection calls.

Related

Implement annotation processor that allows to call method only if variable annotated with annotation (like Rust mut)

I think it's better to start with the idea I want to implement. I'm really inspired by Rust mut pointers so the same type can be immutable and mutable at same time. And I'm thinking is it possible to implement something like this for JVM.
It looks I just need to create annotation #Mutates to annotate methods that changes current class state and annotation #Mutable to annotate local variable, fields and args. Logic of processor is not too hard. For every invocation of method annotated by #Mutates I need to check that corresponding variable/field/arg is annotated by #Mutable. And if method calls any #Mutates method on fields or does assignment (= operator) that method must be annotated by #Mutates as well.
The main problem I don't know where to start as I don't have experience with annotation processing. From my limited understanding I can't use Annotation Processor as it isn't supposed analyze code of methods... So it seems I need to create some compiler plugin (two: for Java and for Kotlin).
Can somebody give me a piece of advice - is it possible at all to do that and how hard is this (so I can estimate efforts and time I will need for that and decide is it worthwhile or not)
The standard annotation processing interface does not provide access to the bodies of methods. However, other frameworks do. For example, the Checker Framework provides an API for annotation processing that descends into method bodies. Building on the Checker Framework, you can create an annotation processor that enforces your mutability rules at compile time: the annotation processor would halt compilation with a javac error message if a rule is violated.
Dozens of annotation processors have been built on the Checker Framework, and it is used daily at Amazon, Facebook, Google, Uber, etc.
Disclaimer: I am one of the maintainers of the project.

Java inheritance not recognised in reflection

I generally oppose extension since it creates a very strong connection between classes, which is easy to accidentally break.
However, I finally thought I'd found a reasonable case for it - I want to optionally use a compressed version of a file type in an existing system. The compressed version would be almost as quick as the uncompressed, and would have exactly the same methods available (i.e. read and write) - the only difference would be in the representation on disk. Therefore, I had the compressed version extend the uncompressed version so that either kind of file could be used, just by optionally insantiating the other type.
public class CompressedSpecialFile extends SpecialFile(){ ... }
if (useCompression){
SpecialFile = new CompressedSpecialFile();
} else {
SpecialFile = new SpecialFile();
}
However, at a later point in the program, we use reflection:
Object[] values = new Object[]{SpecialFile sf, Integer param1, String param2, ...}
Class myclass = Class.forName(algorithmName);
Class[] classes = // created by calling .getClass on each object in values
constructor = myclass.getConstructor(classes);
Algorithm = (Algorithm) constructor.newInstance(values)
Which all worked fine, but now the myclass.getConstructor class throws a NoSuchMethodException since the run-time type of the SpecialFile is CompressedSpecialFile.
However, I thought that was how extension is supposed to work - since CompressedSpecialFile extends SpecialFile, any parameter accepting a SpecialFile should accept a CompressedSpecialFile. Is this an error in Java's reflection, or a failure of my understanding?
Hmm, the response to this bug report seems to indicate that this is intentional.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4301875
We cannot make this change for compatibility reaons. Furthermore, we
would expect that getConstructor should behave analogously to getDeclaredMethod,
which also requires an exact match, thus it does not make sense to change one
without changing the other. It would be possible to add an additional suite of
methods that differed only in the way in which the argument types were matched,
however.
There are certainly cases where we might want to apply at runtime during
reflection the same overload-resolution algorithm used statically by the
compiler, i.e., in a debugger. It is not difficult to implement this
functionality with the existing API, however, so the case for adding this
functionality to core reflection is weak.
That bug report was closed as a duplicate of the following one, which provides a bit more implementation detail:
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=1b08c721077da9fffffffff1e9a6465911b4e?bug_id=4287725
Work Around
Users of getMethod must be precise identifying the Class passed to the argument.
Evaluation
The essence of this request is that the user would like for Class.getMethod
to apply the same overloading rules as the compiler does. I think this is
a reasonable request, as I see a need for this arising frequently in certain
kinds of reflective programs, such as debuggers and scripting interpreters,
and it would be helpful to have a standard implementation so that everybody
gets it right. For compatibility, however, the behavior of the existing
Class.getMethod should be left alone, and a new method defined. There is
a case for leaving this functionality out on the basis of footprint, as it
can be implemented using existing APIs, albeit somewhat inefficiently.
See also 4401287.
Consensus appears to be that we should provide overload resolution in
reflection. Exactly when such functionality is provided would depend largely
on interest and potential uses.
For compatibility reasons, the Class.get(Declared)+{Method,Constructor}
implementation should not change; new method should be introduced. The
specification for these methods does need to be modified to define "match". See
bug 4651775.
You can keep digging into those referenced bugs and the actual links I provided (where there's discussion as well as possible workarounds) but I think that gets at the reasoning (though why a new method reflecting java's oop in reflection as well has not yet been implemented, I don't know).
In terms of workarounds, I suppose that for the one-level-deep version of inheritance, you can just call getSuperclass() on each class whose name is that of the extending class, but that's extremely inelegant and tied to you using it only on your classes implementing in the prescribed manner. Very kludgy. I'll try and look for another option though.

Java Annotations and apt (fundamentals)

I'm really rolling up my sleeves and trying to understand Java annotations for the first time, and have read the Sun, Oracle and Wikipedia articles on the subject. They're easy to understand conceptually, but am finding it difficult putting all the pieces of the puzzle together.
The following example is probably terrible engineering, but just humor me (it's an example!).
Let's say I have the following class:
public Widget
{
// ...
public void foo(int cmd)
{
switch(cmd)
{
case 1:
function1();
break;
case 2:
function2();
break;
case 3:
default:
function3();
break;
}
}
}
Now, somewhere else in my project, I have another class, SpaceShuttle, that has a method called blastOff():
public class SpaceShuttle
{
// ...
public void blastOff()
{
// ...
}
}
Now then, I want to configure an annotation called Widgetize so that any methods annotated with #Widgetize will have Widget::foo(int) invoked prior to their own call.
#interface Widgetize
{
int cmd() default 2;
}
So now let's revisit SpaceShuttle:
public class SpaceShuttle
{
// ...
#Widgetize(3)
public void blastOff()
{
// Since we pass a cmd of "3" to #Widgetize,
// Widget::function3() should be invoked, per
// Widget::foo()'s definition.
}
}
Alas, my questions!
I assume that somewhere I need to define an annotation processor; a Java class that will specify what to do when #Widgetize(int) annotations are encountered, yes? Or does this happen in, say, XML config files that get fed into apt (like the way ant reads build.xml files)?
Edit: If I was correct about these annotation processors in question #1 above, then how do I "map"/"register"/make known these processors to the apt?
In buildscripts, is apt typically ran before javac, so that annotation-based changes or code generation takes place prior to the compile? (This is a best practices-type question).
Thanks and I apologize for my code samples, they turned out a lot bulkier than I intended them to (!)
This sounds more like AOP (Aspect oriented programming) than annotations. The topics are often confused since AOP uses annotations to achieve it's goals. Rather than reinvent AOP from scratch, I would recommend looking up and existing AOP library such as AspectJ.
However, to answer your specific question, there are two possible approaches to achieve your goal.
Runtime Approach
This is the approach typically taken by container frameworks (like Spring). The way it works is that instead of instantiating your classes yourself, you ask a container for an instance of your class.
The container has logic to examine the class for any RuntimeAnnotations (like #Widgetize). The container will then dynamically create a proxy of your class that calls the correct Widgetize method first and then calls the target method.
The container will then return that proxy to the original requester. The requester will still thing he got the class (or interface) that he asked for and be completely unaware of the proxying behavior added by the container.
This is also the behavior used by AspectJ.
Enhancement Approach
This is the approach taken by AspectJ. To be honest, I don't know a lot of the details of how it works. Somehow, AspectJ will scan your class files (the byte code), figure out where the annotations are, and then modify the byte code itself to call the proxy class instead of the actual class.
The benefit of this approach is that you don't need to use a container. The drawback is that you now have to do this enhancement step after you compile your code.
I assume that somewhere I need to
define an annotation processor; a Java
class that will specify what to do
when #Widgetize(int) annotations are
encountered, yes? Or does this happen
in, say, XML config files that get fed
into apt (like the way ant reads
build.xml files)?
In Java 1.6, the standard way to define annotation processors its through the ServiceLoader SPI.
In buildscripts, is apt typically ran
before javac, so that annotation-based
changes or code generation takes place
prior to the compile? (This is a best
practices-type question).
APT must take place before compilation, as it operates on source files (actually on syntax trees).
I use method interceptors often with Hibernate. Hibernate requires that a transaction be started and committed round every query. Rather than have lots of duplicate code I intercept every Hibernate method and start the transaction in the interceptor.
I use AOP Alliance method interceptors in conjunction with Google Guice for this. Using these you use your Widgetise annotation and then use Guice to say where you see this annotation use this method interceptor. The following Guice snippet does this.
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), new TransactionalInterceptor);
The interceptor catches the method, you can then call foo and then the tell the method interceptor to proceed with invocation of the original method. For example (in a simplified form):
public class Interceptor implements MethodInterceptor {
//PUT ANY DEPENDENCIES HERE IN A CONSTRUCTOR
public Object invoke(MethodInvocation invocation) throws Throwable {
//DO FOO HERE
result = invocation.proceed();
return result;
}
}
This might be a little confusing and it took me a while to get my head around but it is quite simple once you understand it.
It seems that the basis of your confusion is an incorrect belief that Annotations are something more than just Metadata. Check out this page from the JSE 1.5 language guide. Here is a relevant snippet:
Annotations do not directly affect
program semantics, but they do affect
the way programs are treated by tools
and libraries, which can in turn
affect the semantics of the running
program. Annotations can be read from
source files, class files, or
reflectively at run time.
In your code
#Widgetize(3)
public void blastOff()
does not cause Widget::function3() to execute (asside: in java we reference a member as Widget.function3()) The annotation is just the equivalent of a machine-readable comment (i.e. metadata).
Annotations can be processed both at compile time and at runtime. To process them at runtime requires using the reflection API, which will have a performance impact if it's not done smartly.
It's also possible to process annotations at compile time. The goal is to generate a class which can then be used by your code. There is a specific interface annotation processors have to satisfy, and they have to be declared in order to be executed.
Take a look at the following article for an example which is structurally simple to your use case:
Annotation processing 101

cheap way to mock an interface with no runtime overhead

Suppose I have an interface with lots of methods that I want to mock for a test, and suppose that I don't need it to do anything, I just need the object under test to have an instance of it. For example, I want to run some performance testing/benchmarking over a certain bit of code and don't want the methods on this interface to contribute.
There are plenty of tools to do that easily, for example
Interface mock = Mockito.mock(Interface.class);
ObjectUnderTest obj = ...
obj.setItem(mock);
or whatever.
However, they all come with some runtime overhead that I would rather avoid:
Mockito records all calls, stashing the arguments for verification later
JMock and others (I believe) require you to define what they going to do (not such a big deal), and then execution goes through a proxy of various sorts to actual invoke the method.
Good old java.lang.reflect.Proxy and friends all go through at least a few more method calls on the stack before getting to the method to be invoked, often reflectively.
(I'm willing to be corrected on any of the details of those examples, but I believe the principle holds.)
What I'm aiming for is a "real" no-op implementation of the interface, such as I could write by hand with everything returning null, false or 0. But that doesn't help if I'm feeling lazy and the interface has loads of methods. So, how can I generate and instantiate such a no-op implementation of an arbitrary interface at runtime?
There are tools available such as Powermock, CGLib that use bytecode generation, but only as part of the larger mocking/proxying context and I haven't yet figured out what to pick out of the internals.
OK, so the example may be a little contrived and I doubt that proxying will have too substantial an impact on the timings, but I'm curious now as to how to generate such a class. Is it easy in CGLib, ASM?
EDIT: Yes, this is premature optimisation and there's no real need to do it. After writing this question I think the last sentence didn't quite make my point that I'm more interested in how to do it in principle, and easy ways into dynamic class-generation than the actual use-case I gave. Perhaps poorly worded from the start.
Not sure if this is what you're looking for, but the "new class" wizard in Eclipse lets you build a new class and specify superclass and/or interface(s). If you let it, it will auto-code up dummy implementations of all interface/abstract methods (returning null unless void). It's pretty painless to do.
I suspect the other "big name" IDEs, such as NetBeans and Idea, have similar facilities.
EDIT:
Looking at your question again, I wonder why you'd be concerned about performance of auto proxies when dealing with test classes. It seems to me that if performance is an issue, you should be testing "real" functionality, and if you're dealing with mostly-unimplemented classes anyway then you shouldn't be in a testing situation where performance matters.
It would take a little work to build the utility, but probably not too hard for basic vanilla Java interface without "edge cases" (annotations, etc), to use Javassist code generation to textually create a class at runtime that implements null versions of every method defined on the interface. This would be different from Javassist ProxyFactory (Or CGLib Enhancer) proxy objects which would still have a few layers of indirection. I think there would be no overhead in the resulting class from the direct bytecode generation mode. If you are brave you could also dive into ASM to do the same thing.

Java Annotations

What is the purpose of annotations in Java? I have this fuzzy idea of them as somewhere in between a comment and actual code. Do they affect the program at run time?
What are their typical usages?
Are they unique to Java? Is there a C++ equivalent?
Annotations are primarily used by code that is inspecting other code. They are often used for modifying (i.e. decorating or wrapping) existing classes at run-time to change their behavior. Frameworks such as JUnit and Hibernate use annotations to minimize the amount of code you need to write yourself to use the frameworks.
Oracle has a good explanation of the concept and its meaning in Java on their site.
Also, are they unique to Java, is there a C++ equivalent?
No, but VB and C# have attributes which are the same thing.
Their use is quite diverse. One typical Java example, #Override has no effect on the code but it can be used by the compiler to generate a warning (or error) if the decorated method doesn't actually override another method. Similarly, methods can be marked obsolete.
Then there's reflection. When you reflect a type of a class in your code, you can access the attributes and act according to the information found there. I don't know any examples in Java but in .NET this is used by the compiler to generate (de)serialization information for classes, determine the memory layout of structures and declare function imports from legacy libraries (among others). They also control how the IDE form designer works.
/EDIT: Attributes on classes are comparable to tag interfaces (like Serializable in Java). However, the .NET coding guidelines say not to use tag interfaces. Also, they only work on class level, not on method level.
Anders gives a good summary, and here's an example of a JUnit annotation
#Test(expected=IOException.class)
public void flatfileMissing() throws IOException {
readFlatFile("testfiles"+separator+"flatfile_doesnotexist.dat");
}
Here the #Test annotation is telling JUnit that the flatfileMissing method is a test that should be executed and that the expected result is a thrown IOException. Thus, when you run your tests, this method will be called and the test will pass or fail based on whether an IOException is thrown.
Java also has the Annotation Processing Tool (apt) where not only you create annotations, but decide also how do these annotations work on the source code.
Here is an introduction.
To see some cool stuff you can do with Annotations, check out my JavaBean annotations and annotation processor.
They're great for generating code, adding extra validations during your build, and I've also been using them for an error message framework (not yet published -- need to clear with the bosses...).
The first thing a newcomer to annotations will ask about annotations is: "What is an annotation?" It turns out that there is no answer to this question, in the sense that there is no common behavior which is present in all of the various kinds of java annotations. There is, in other words, nothing that binds them together into an abstract conceptual group other than the fact that they all start with an "#" symbol.
For example, there is the #Override annotation, which tells the compiler to check that this member function overrides one in the parent class. There is the #Target annotation, which is used to specify what kinds of objects a user defined annotation (a third type of construct with nothing in common with other kinds of annotation) can be attached to. These have nothing to do with one another except for starting with an # symbol.
Basically, what appears to have happened is that some committee responsible for maintaining the java language definition is gatekeeping the addition of new keywords to the java language, and therefore other developers are doing an end run around that by calling new keywords "annotations". And that's why it is hard to understand, in general what an annotation is: because there is no common feature linking all annotations that could be used to put them in a conceptual group. In other words, annotations as a concept do not exist.
Therefore I would recommend studying the behavior of every different kind of annotation individually, and do not expect understanding one kind of annotation to tell you anything about the others.
Many of the other answers to this question assume the user is asking about user defined annotations specifically, which are one kind of annotation that defines a set of integers or strings or other data, static to the class or method or variable they are attached to, that can be queried at compile time or run time. Sadly, there is no marker that distinguishes this kind of annotation from other kinds like #interface that do different things.
By literal definition an annotation adds notes to an element. Likewise, Java annotations are tags that we insert into source code for providing more information about the code. Java annotations associate information with the annotated program element. Beside Java annotations Java programs have copious amounts of informal documentation that typically is contained within comments in the source code file. But, Java annotations are different from comments they annotate the program elements directly using annotation types to describe the form of the annotations. Java Annotations present the information in a standard and structured way so that it could be used amenably by processing tools.
When do you use Java's #Override annotation and why?
The link refers to a question on when one should use the override annotation(#override)..
This might help understand the concept of annotation better.Check out.
Annotations when it comes to EJB is known as choosing Implicit middle-ware approach over an explicit middle-ware approach , when you use annotation you're customizing what you exactly need from the API
for example you need to call transaction method for a bank transfer :
without using annotation :
the code will be
transfer(Account account1, Account account2, long amount)
{
// 1: Call middleware API to perform a security check
// 2: Call middleware API to start a transaction
// 3: Call middleware API to load rows from the database
// 4: Subtract the balance from one account, add to the other
// 5: Call middleware API to store rows in the database
// 6: Call middleware API to end the transaction
}
while using Annotation your code contains no cumbersome API calls to use the middle-
ware services. The code is clean and focused on business logic
transfer(Account account1, Account account2, long amount)
{
// 1: Subtract the balance from one account, add to the other
}

Categories