Here's a problem I am facing.
I am writing a plugin. There is an interface called SystemObject, and a default getter.
public class MyPlugin extends Plugin {
#override
public SystemObject getSystemObject() {
return super.getSystemObject();
}
}
SystemObject interface has a method called getScreenSize() which I would like to proxy or intercept. When I create a proxy class, or simply implement this SystemObject interface myself, I get a class cast exception.
This is because the caller for getSystemObject (part of the plugin system) has this in their code (found via reverse-engineering):
private void foo() {
SystemObjectImpl impl = (SystemObjectImpl)plugin.getSystemObject();
}
My question is: is there any way I can proxy calls on the SystemObject interface?
I tried implementing the interface and using java reflection proxy invocation to no avail. Unfortunately, I'm not responsible for running the java process, so I can't use an agent.
Cheers!
You could use something like CGLIB to create a proxy class that extends SystemObjectImpl.
Related
I am developing a library which needs some configuration information from project which would include this library. What I was thinking is to having some abstract methods in my library and force application to implement these methods.
What I am looking for is:
Class A in library having some static abstract methods, say
having a method named getURL();
A class B implements these static
methods in actual application and implement method getURL() from
class A.
In my library, I called A.getURL(), it should call method
implementation from class B which extends class A and should return me the url.
But an abstract method can't be static in Java. Is there some workaround to achieve same like functionality.
public abstract class A {
protected static A INSTANCE;
public static String getURL() {
return INSTANCE.getURL();
}
protected abstract String getURL0();
}
class B extends A {
static {
INSTANCE = new B();
}
#Override
protected String getURL0() {
return "application-specific url";
}
}
A static abstract method makes no sense, since the notion that an abstract method should be implemented by an extending class (which is part of OO), and static denotes a non instance method (not OO).
But I had a similar problem in a J2EE project recently, in which the library needed some specific configuration depending on the project that used it.
What we decided to do is to have a configuration file with a specific name in the project, that the library should read as soon as loaded. If the file and/or the required configurations were not found, an exception is thrown (you can create your own).
I think this way you can decouple implementation of the library from the projects using it.
Based on your answers to questions I would recommend the following:
Define an interface for a class that retrieves the properties like so:
interface LibaryDetails {
URL getURL();
String getName();
}
Then create a Factory method of some kind which causes your Library to run and do it's thing. Refactor your code out of the main so it can be accessed from here. Have this method take the interface as a parameter:
public class LibraryFactory{
public static void startLibrary(LibaryDetails details){
URL url = details.getURL();
String name = details.getName();
// start Library things
}
}
Now your Library only needs to expose the interface and the static Factory. Your Applications just needs to pass it's implementation of the LibraryDetails interface to the factory method and your library can access the information.
In all of the Guice examples I have found, getting an instance involves calling Injector.getInstance() with the concrete class as a parameter. Is there a way to get an instance from Guice using only the interface?
public interface Interface {}
public class Concrete implements Interface {}
Interface instance = injector.getInstance(Interface.class);
Thanks
Actually that's exactly what Guice is made for.
In order to make getInstance() work with an interface you'll need to first bind an implementation of that interface in your module.
So you'll need a class that looks something like this:
public class MyGuiceModule extends AbstractModule {
#Override
protected void configure() {
bind(Interface.class).to(Concrete.class);
}
}
Then when you create your injector you just need to pass an instance of your module in:
Injector injector = Guice.createInjector(new MyGuiceModule());
Now your call to injector.getInstance(Interface.class) should return a new instance of Concrete using the default constructor.
Of course there are many many more ways you can do bindings but this is probably the most straight forward.
It works for interface as well:
bind( Interface.class ).to( Concrete.class );
Without using a Module, you can also specify the implementation class to be used by default, directly in the interface declaration:
#ImplementedBy(Concrete.class)
public interface Interface {}
This doesn't necessarily fit every situation but I found this comes in handy most of the times.
Additionnally, when using #ImplementedBy annotation, you can still override the implementation class by binding another concrete class in a Module. That can also be useful.
I was wondering if it is possible to make a generic webservice method in java like this:
#WebMethod
public <T extends Foo> void testGeneric(T data){
However when I try to consume this with a Java client I get an error stating:
[ERROR] Schema descriptor {http://####/}testGeneric in message part "parameters" is not defined and could not be bound to Java.
I know it is possible to make a method that takes a parameter such as List and this generates correctly using JAX-WS.
I don't mind if there is a solution that means I am tied to using only a particular technology.
Thanks,
Dan.
I doubt it. But you can define a generic super interface and let your actual service interface extend it with parameters:
public interface BaseService<T>{
T doWhackStuff();
}
public interface WhackyService extends BaseService<Whack>{
}
public interface EvenMoreWhackyService extends BaseService<Whackier>{
}
This approach usually only makes sense if you build your interfaces from multiple components:
public interface BaseService<T>{
T doWhackStuff();
}
public interface ExtendedService<T>{
T doMoreWhackStuff();
}
public interface DoubleWhackyService extends BaseService<Whack>, ExtendedService<Whack>{
}
I have not tested this approach in JAX-WS, but I know it works in Spring / GraniteDS / Flex
I am interested in getting the class being proxied from spring, rather than the proxy.
ie:
public class FooImpl<KittyKat> {
#Transactional
public void doStuff() {
getBar();
// java.lang.ClassCastException: $Proxy26 cannot be cast to
// com.my.foo.Bar
}
}
public abstract class AbstractFoo<T extends AbstractBar> {
public String barBeanName;
protected T getBar() {
// java.lang.ClassCastException: $Proxy26 cannot be cast to
// com.my.foo.Bar
return (T)appContext.getBean(barBeanName);
}
}
public class KittyCat extends AbstractBar {
...
}
public abstract class AbstractBar {
...
}
Are you trying to get the proxied bean only because of the ClassCastException? If you could cast to Bar, would you happy with that?
When Spring creates a proxy, it checks to see if the bean class implements any interfaces. If it does, then the generated proxy will also implement those interfaces, but it will not extend the target bean's class. It does this using a standard java.lang.reflect.Proxy. This seems to be the case in your example.
If the target bean's class does not implement any interfaces, then Spring will use CGLIB to generate a proxy class which is a subclass of the target bean's class. This is sort of a stop-gap measure for proxying non-interface beans.
You can force Spring to always proxy the target class, but how you do that depends on how you created the Bar proxy to begin with, and you haven't told us that.
The generally preferred solution is to refer to your proxied beans by their interfaces, and everything works nicely. If your Bar class implement interfaces, could your Foo not refer to that interface?
I am looking for a way to do the following:
A Project :
Defines an abstract class that is called when some events happen (event handler if you will)
Defines the engine that will fire the events using the event handler above
B Project:
Defines the implementation for the abstract class
Runs the engine.
How can i register the implementation class and make sure that is the one being called when the engine runs.
EDIT 1: By register i mean i must somehow define which is the implementation that should be called for that given abstract object
Sorry if the question isn't too clear, let me know if you need some more details
Something like this?
class A implements EventHandlerForB {
...
}
public class B {
private EventHandlerForB eventHandler;
public void registerEventHandler(EventHandlerForB eventHandler) {
this.eventHandler = eventHandler;
}
...
}
public interface EventHandlerForB {
...
}
At runtime, you can have the name of the implementation passed in your A project (with a properties file or a Java system property).
Then you find this class in the classpath with class.forName() and instantiate it with newInstance().
But you'd prefer using a framework like Guice or Spring, that will allow you to glue stuff together in a clean way.
there are several "patterns" that try to address this issue. Using only JDK (6 or above) classes you may want to take a look at java.util.ServiceLoader