I am developing an application that makes use of the Java Interface as more than a Java interface, i.e., During runtime, the user should be able to list the available methods within the interface class, which may be anything:
private Class<? extends BaseInterface> interfaceClass.
At runtime, I would like to enum the available methods, and then based on what the user chooses, invoke some method.
My question is: Does the Java "Interface" architecture provide any method for me to peek and invoke methods without using the Reflection API?
I wish there were something like this (Maybe there is):
private Interface<? extends BaseInterface> interfaceAPI;
public void someMethod(){
interfaceAPI.listMethods();
interfaceAPI.getAnnotations();
}
Maybe there is some way to use Type Generics to accomplish what I want?
Thanks,
Phaedrus
This is exactly what Reflection was built for.
Take a look at Apache Commons BeanUtils. It's an excellent library for programmatically discovering an object's methods and properties easily (i.e. without writing low-level reflection code). I've used it on several projects. It also provides an easier API for accessing those object members once they're discovered. PropertyUtils and MethodUtils are good places to start.
My question is: Does the Java "Interface" architecture provide any method for me to peek and invoke methods without using the Reflection API?
a) No, reflection is the only way to do that
b) don't do that at all. If you want a dynamic language, use Groovy. It's syntax is (can be) almost identical to java, but it has most of this functionality built in already. (Many other languages will also work, but Groovy is closest to Java when comparing the syntax)
Reflection is the only way to list methods of an arbitrary object. Well, parsing the bytecode also works, but it's tedious.
Unfortunately it looks like reflection is the only way to go. Unfortunate because reflection is not only slower but programming and maintaining is a hassle. So I suggest you use apache bean util library. (specifically methodutils.)
Although there's no way around reflection here, it can be made relatively painless if you use annotations to mark your callable methods. An example of this approach at work is the javax.jws annotation set for webservices. The ideas used there can be really useful, you can define a display name for each of your methods/parameters for example.
Reflection with Annotations is working Nicely
for (Method m : interfaceClass.getMethods()) {
if (m.isAnnotationPresent(UIf.class)) {
UIf x = m.getAnnotation(UIf.class);
addDefinedCommand( new CommandDef(
interfaceClass,
u,
x.name().isEmpty() ? m.getName() : x.name(),
x.description())
);
}
}
Related
C#'s extension methods are great for adding syntactic sugar. Java extension methods are great for allowing library developers to add methods to their interfaces.
I am a non-library Java developer and know I will reap a lot of benefits from getting new functionality from libraries, but I would still like to have the syntactic sugar capabilities of C# extension methods.
Is this, or will this be possible in future versions of Java?
eg: I would like to add methods to the String class...
String data = StringUtils.capitalize("abcd"); // instead of this
String data = "abcd".capitalize() // I would like to do this
Please don't focus on this particular example, I am only showing the class of functionality I want to be able to achieve.
Java does not have this feature, nor is it likely to have it anytime soon.
Groovy however does have a very similar feature, and it also runs on the JVM. Perhaps that's an option.
I suspect you're thinking of a planned addition to Java 8 that will allow you to add methods, with default implementations, to an interface -- so that you can add new methods without breaking all existing code. This is only of use to you if you control the interface type -- so it would not be of use for String, because String is not an interface.
After comming from Ruby world, I'm having little problems doing TDD in Java. The biggest issue is when I have application that is just communicating with external API.
Say I want to just fetch some data from Google Calendar, or 5 tweets from some Twitter user and display it.
In Ruby, I don't have any problems, because I can monkey-patch the API library in tests directly, but I have no such option in Java.
If I think about this in terms of MVC, my model objects are directly accessing the API through some library. The question is, is this bad design? Should I always wrap any API library in some interface, so I can mock/stub it in Java?
Because when I think about this, the only purpose of that interface would be to simulate (please don't kill me for saying this) the monkey-patch. Meaning that any time I use any external resource, I have to wrap each layer in interface that can be stubbed out.
# do I have to abstract everything just to do this in Java?
Twitter.stub!(:search)
Now you might say that I should always abstract away the interface, so I can change the underlying layer to anything else. But if I'm writing twitter app, I'm not going to change it to RSS reader.
Yes, I can add for example Facebook and then it would make sense to have interface. But when there is no other resource that can be substituted for the one I'm using, than I still have to wrap everything in interfaces to make it testable.
Am I missing something, or is this just a way to test in the Java world?
Using interfaces is just generally good practice in Java. Some languages have multiple inheritance, others have duck typing, Java has interfaces. It's a key feature of the language, it lets me use
different aspects of a class in different contexts and
different implementations of the same contract without changing client code.
So interfaces are a concept you should embrace in general, and then you would reap the benefits in situations like this where you could substitute your services by mock objects.
One of the most important books about Java best practices is Effective Java by Joshua Bloch. I would highly suggest you to read it. In this context the most important part is Item 52: Refer to objects by their interfaces. Quote:
More generally, you should favor the use of interfaces rather than
classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface
types. The only time you really need to refer to an object’s class is when you’re
creating it with a constructor.
And if you take things even further (e.g. when using dependency injection), you aren't even calling the constructor.
One of the key problems of switching languages is that you have to switch the way of thinking too. You can't program language x effectively while thinking in language y. You can't program C effectively without using pointers, Ruby not without duck typing and Java not without Interfaces.
Wrapping the external API is the way I would do this.
So, as you already said, you would have an interface and two classes: the real one and the dummy implementation.
Yes, it may seem unreasonable from the perspective of some services indeed being specific, like Twitter. But, this way your build process doesn't depend on external resources. Depending on external libraries isn't all that bad, but having your tests depend on actual data present or not present out there on the web can mess up the build process.
The easiest way is to wrap the API service with your interface/class pair and use that throughout your code.
I understand that what you want are Mock objects.
As you described it, one of the ways one can generate "test versions" of objects is by implementing a common interface and using it.
However, what you are missing is to simply extend the class (provided that it is not declared final) and override the methods that you want to mock. (NB: the possibility of doing that is the reason why it is considered bad form for a library to declare its classes final - it can make testing considerably harder.)
There is a number of Java libraries that aim in facilitating the use of Mock objects - you can look at Mockito or EasyMock.
Mockito is more handy and like your ruby mocks.
You can "monkey-patch" an API in Java. The Java language itself does not provide specific means to do it, but the JVM and the standard libraries do. In Ruby, developers can use the Mocha library for that. In Java, you can use the JMockit library (which I created because of limitations in older mocking tools).
Here is an example JMockit test, equivalent to the test_should_calculate_value_of_unshipped_orders test available in Mocha documentation:
#Test
public void shouldCalculateValueOfUnshippedOrders()
{
final Order anOrder = new Order();
final List<Order> orders = asList(anOrder, new Order(), new Order());
new NonStrictExpectations(Order.class)
{{
Order.findAll(); result = orders;
anOrder.getTotalCost(); result = 10;
}};
assertEquals(30, Order.unshippedValue());
}
I have read about Java Reflections but till date it has been a vague concept to me. Can someone give a brief details with short example on how to use reflections in Java ?
Thanks.
I have read about Java Reflections but
till date it has been a vague concept
to me.
Here is a quick into to reflection in java:
Structural introspection. Basic reflection deals with the introspection of object at run-time. This means that you can learn the structure of objects and classes at run-time programmatically, e.g. get the class of the object, list the methods of the class, list the fields defined in the class, etc.
Reflective invocation and instantiation. With reflection you can invoke a method at run-time which is not defined at compile-time, e.g. invoke method named M on object O, where M is read in a configuration file. You can also instantiate object dynamically without knowing the class at compile-time.
Annotations. Then you can move one level up in the meta levels, and play with annotations. Annotations describe other elements such as class, method and fields. Many framework rely on this.
Dynamic proxy. Dynamic proxy can be generated at run-time. In this case, it's really like if you create a class dynamically at run-time. To use with care, but definitively handy and powerful in some cases.
I guess you will start with structural introspection. There are links to tutorials in the other answers, but I hope this gives you an overview of what else can be done.
I guess the article 'Using Java Reflection' found on sun.com might be a good starting point.
It's primarily to be used to access classes/methods/fields programmatically (i.e. during runtime instead of compiletime). Good real world API's which uses reflection intensively are ORM's like Hibernate/JPA.
You can find here a Sun tutorial on the subject (click Next link at the bottom to paginate through it).
Something worth mentioning as well is Javassist. Not only does it have reflective abilities, but it also allows run-time bytecode manipulation using ordinary source syntax! Once you've gotten into reflection a bit more (which you probably have by now), you'll truly appreciate it's beauty.
Is there any way we can inject new methods and properties into classes during run-time.
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html states we may do that by using Groovy.
Is it possible by just doing using Java?
Is it possible by just doing using
Java?
The simple answer is an emphatic "You don't want to do that!".
It is technically possible, but not without resorting to extremely complex, expensive and fragile tricks like bytecode modification1. And even then, you have to rely on dynamic loading to access the modified type and (probably) reflection to make use of its new members. In short, you would be creating lots of pain for yourself, for little if any gain.
Java is a statically typed language, and adding / modifying class type signatures can break the static typing contract of a class.
1 - AspectJ and the like allow you to inject additional behaviour into a class, but it is probably not the "runtime" injection that you are after. Certainly, the injected methods won't be available for statically compiled code to call.
So if you were really crazy, you could do something like what they outline here. What you could do is load the .java file, find the correct insertion point, add whatever methods you need to, call the java compiler and reload the class. Good luck debugging that mess though :)
Edit This actually might be of some use...
You can do some quite funky things with AOP, although genuine modification of classes at runtime is a pretty hairy technique that needs a lot of classloading magic and sleight of hand.
What is easier is using AOP techniques to generate a subclass of your target class and to introduce new methods into this instead, what AOP called a "mixin" or "introduction". See here to read how Spring AOP does it, although this may be quite lame compared to what you're actually trying to achieve.
Is it possible by just doing using Java?
Quite so, the "only" thing you have to do is define an instrumentation agent which supplies an appropriate ClassFileTransformer, and you'll have to use reflection to invoke the added methods. Odds are this isn't what you want to do, though, but it's doable and there's a well-defined interface for it. If you want to modify existing methods you may be interested in something like AspectJ.
While it might be possible, it is not useful.
How would you access these new fields and methods?
You could not use these methods and fields directly (as "ordinary" fields and methods), since they wouldn't be compiled in.
If all you want is the possibility to add "properties" and "methods", you can use a Map<String, Object> for the "dynamic properties", and a Map<String, SuitableInterface> for the "dynamic methods", and look them up by name.
If you need an extension language for Java, an embedded dynamic language (such as Javascript, or Groovy) can be added; most of these can access arbitrary java objects and methods.
Is there a Java equivalent for the __call of PHP?
It would make sense to me if that's not the case, because it would probably result in compiler errors.
From the PHP manual on magic methods:
__call() is triggered when invoking inaccessible methods in an object context.
This sort of dynamic method/attribute resolution which is common in dynamically typed languages such as PHP, Python and Ruby is not directly supported in the Java language.
The effect can be approximated using Dynamic Proxies which requires you to have an interface for which the implementation will be dynamically resolved. Third party libraries such as CGLIB allow similar things to be done with normal Java classes.
This API based, special case interception of method invocation is not as convenient as the direct, always on support you can get with __call in PHP or equivalent features in other dynamically typed languages (such as __getattr__ in Python). This difference is due the fundamentally different ways in which method dispatch is handled in the two types of languages.
No, there is not.
as other said, java doesn't support this.
it does have something called a proxy class which can intercept calls to known methods (rather than undefined methods as in php's __call()). a proxy can be created dynamically as a wrapper around any interface:
http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html#proxy
http://java.sun.com/j2se/1.4.2/docs/guide/reflection/proxy.html#examples
Foo foo = (Foo) DebugProxy.newInstance(new FooImpl());
foo.bar(null);
foo looks like a Foo, but all the calls are intercepted by FooImpl's invoke() method.
to create a truly de novo class at runtime with dynamic methods in its interface, you can essentially compile a class definition and use java's class loader to import it at runtime. a tool like apache's JCI or Arch4J can handle this for you. still, the class will only have those methods you specify.
No, Java doesn't have that feature. For one thing, I think it would make overloading pretty much impossible (some argue overloading is a bad idea anyway, but this isn't the right forum for that debate). Beyond that, I get the sense that the designers of Java just feel that the flexibility something like that (I know it from Perl where it's called AUTOLOAD) is outweighed by the guarantee that any code that compiles is only calling methods that actually exist (barring binary incompatibilities).
No, java is a compiled language and the compiler wants to make sure that every function you call actually exists.