Sorry about the strange topic name, could not find one that fitted well.
To my problem, i want to create something dynamic in Java, it is a very simple class that can take an event and throw it along, sadly have the system i am using be made so each event must have it own method where the event is the argument of the method, but the good news is that we can add as many event listener classes as we want! I wan my program to be able to dynamic add and remove the methods that are being listened to, by add and remove the listen classes.
I am not good with Java but have a fair deal expirence with C#, so i attacked my problem as i would there and created this class.
public class TESPluginDynListener<T> implements Listener {
TESPlugin plugin;
public TESPluginDynListener(TESPlugin plugin){
this.plugin = plugin;
}
#EventHandler(ignoreCancelled=false, priority = EventPriority.LOW)
public void onDynEvent(T event){
if(event instanceof Event)
plugin.onEvent((Event)event);
}
}
This seems to work fine, but my problem is, that the event i have to register do i get as a String, example "some.package.someEvent", and i have no idea how to translate that into the Type T so i can add the listener class.
So how can i create an instance my class TESPluginDynListener where T is translated from a String? I am not interested in doing a lot of if else, as i want this to be as dynamic as possible!
Here is an idea of what i am trying to do
String eventClass = "some.package.someEvent";
TESPluginDynListener listener = new TESPluginDynListener<Type.FromName(eventClass)>(this);
eventhandeler.RegisterListener(listener);
It sounds like you're looking for Class.forName and Class.newInstance.
On the other hand, bear in mind that type erasure in generics means you don't really need to know T in order to build a TESPluginDynListener... you probably want to take Class<T> in the constructor for TESPluginDynListener and use Class.isInstance rather than instanceof within onDynEvent.
Related
I am having issues designing a clean solution for sending messages of different types using an observer pattern style solution.
I have a client application connecting to a server (that I cannot change) over a tcp socket. I can send and receive json encoded messages which will always contain a "msg" parameter which defines what type of message it is. Also note that I can recieve messages that are sent to several clients and weren't requested by my own client (if someone sends a chat message, for example).
Example:
On connect I receive {"msg":"ServerInfo","version":"1.0a"}
Sending {"msg":"Ping"} replies with {"msg":"Ping","time":1381358623}
I could receive {"msg":"Chat", "from":"Person", "text":"Hello everyone"} at any time
Some of the messages are more complex and can have nested objects, for example
{
"msg":"SampleData",
"people":[{
"name":"Joe"
"age":25
},{
"name":"Bob",
"age":30
}]
}
There are a couple dozen different types of messages all with varying amounts and types of fields.
I currently have a class which is responsible for listening on the socket and parsing all messages using Gson in to a "BasicMessage" class which only has the "msg" parameter. I have a Map mapping all the message type strings to their respective classes. Once I have the "msg" paremeter I can lookup the class I need to deserialize it to with Gson and then do so. Now I have an instance of the correct class but this is where my design starts falling apart.
I would like to have various other classes have the ability to subscribe to only a few types of messages. The issue is I can't seem to find a way that does this without requiring either a bunch of instanceof's or reparsing everything again in every client.
My initial thought was to use a parameterized interface like so:
public interface MessageListener<T> {
public void onReceivedMessage(T message);
}
then in the class that deserializes the messages, I had a List<MessageListener<Message>> where Message was the abstract class every other Message inherited from. Then I ran in to the type erasure issue where MessageListener<SpecificMessage> doesn't inherit from MessageListener<Message> so I didn't have a way I could add the clients to one simple list. It seemed as though I would have to have a list for each type of message which is also not ideal. Another issue with this design is it would limit me to only using anonymous inner classes for the various message listeners in a class that would need more than one since you also can't implement the same interface twice even if you parameterize it with a different class.
Is there a better pattern that I could be using for this situation? I feel like I might have to use reflection to get this to work "neatly". Ideally, if I want to add another message type I would like it to require simply adding the class for it to deserialize to and perhaps a mapping from its msg string to that class and then be able to start adding listeners for that type of message in another class.
Thanks in advance!
The guava eventbus offers a publish/subscribe messaging component, designed to simplify the implemenation of the classic Observer pattern. Instead of having to explicitly register dedicated Listener or Observer instances with an event emitting object, one registers a class, which is interested in certain events with the bus:
class MyEventListeningClass {
#Subscribe public void onEvent(MyEvent e) {
// react to event
}
}
...
eventBus.register(new MyEventListeningClass());
Registration and dispatching of events to interested subscribers is done through reflection.
As seen already in the question and other answers, Java's type system makes it hard to achieve a similar flexibility with listener interfaces. For the use case in question, the event bus seems to be a good fit, especially when more message types need to be added in the future. Alas the usual caveats of such loose coupling apply: it is harder to reason about, what exactly will happen with a message.
Instead of a list, how about storing a HashMap<Class<? extends Message>, List<MessageListener<? extends Message>>? That buys you a simpler lookup when a message comes in and you have an indeterminate number of listeners interested in an indeterminate number of events. Just look up the list of listeners interested in your deserialized message type. You'd set it up so that you could only add to the map in a way that provides you compile-time checking:
public <T> void addListener(Class<T>, MessageListener<T>) {...}
Also, you're not limited to using anonymous inner classes when you implement these listeners, only inner classes. It might make your classes a little longer, but it helps greatly during debugging if you just line them up at the bottom of each class that needs them like so:
private class SampleDataListener implements MessageListener<SampleData> {
...
public void messageReceived(SampleData message) {...}
}
private class OtherDataListener implements MessageListener<OtherData> {
...
public void messageReceived(OtherData message) {...}
}
Here's a possibility (but note that I haven't tested it). Unfortunately, it will require a certain method to be added to every subclass of BasicMessage; I've tried to make it as short as possible to limit the duplication. In each class SpecificMessage, add this:
public static void addListener (SocketListener s, MessageListener<SpecificMessage> listener)
{
s.addSubclassListener (SpecificMessage.class, listener);
}
I'm assuming SocketListener is the class that would be listening to the socket and later sending messages to the subscribers. (You can change it to whatever's appropriate.)
In SocketListener:
private interface BasicMessageListener {
public void onReceivedMessage (BasicMessage message);
}
protected <T extends BasicMessage> void addSubclassListener (final Class<?> clazz, final MessageListener<T> listener)
{
addBasicMessageListener (clazz, new BasicMessageListener () {
public void onReceivedMessage (BasicMessage message) {
if (message.getClass() != clazz)
throw new ClassCastException ();
listener.onReceivedMessage ((T) message);
}
}
}
addBasicMessageListener will be the method that registers a listener for the class. Since its parameter isn't generic, you should be able to add it to a list. (Note: the typecast to (T) will give you unchecked warnings.) The idea is that if other classes want to register a listener to listen to messages of class SpecificMessageXYZ, they'd use
SpecificMessageXYZ.addListener (theSocketListener, new MessageListener<SpecificMessageXYZ> () {
...
... a listener that takes a SpecificMessageXYZ parameter
...
});
or something to that effect. This still will involve a downcast, but it will be only in one place (in addSubclassListener), rather than having to do an instanceof and downcast in every listener that the other classes may want to register. Whether that's enough of a gain to make up for having to put the duplicated method in every message class, I don't know. However, I can't think of another way without using reflection. I think what you're looking for is some interesting sort of covariance that doesn't exist in Java.
Again, I'll warn you that I haven't actually tried this, except that I ran it through the compiler to make sure I wasn't doing anything illegal. Also please note that my choice of method/class names tends to be lousy.
EDIT: It occurred to me that although (T) message isn't able to perform a check, we already have the information needed to do the check, so we should.
I am creating an android application using Java. I have a boolean variable called "movement". I want to create an event that triggers when the value of "movement" changes. Any pointers in the right direction would be great. Thank you
A variable is not alone, I presume. It resides as a member in a class - right? So the listener interface would be nested in that class, and the class would have a member variable for a listener, and a setBooChangeListener method. And on every change to the variable (it's not public, I hope) you'd call the listener, if any. That's pretty much it.
class C
{
private boolean mBoo; //that's our variable
public interface BooChangeListener
{
public void OnBooChange(boolean Boo);
}
private BooChangeListener mOnChange = null;
public void setOnBooChangeListener(BooChangeListener bcl)
{
mOnChange = bcl;
}
public void setBoo(boolean b)
{
mBoo = b;
if(mOnChange != null)
mOnChange.onBooChange(b);
}
}
There's no way to have the system (Java) watch the variable and automatically fire a listener whenever it's changed. There's no magic.
I wish I could add this as a comment...I agree with the most part with Seva above, however, consider making the class a bean and implementing the PropertyChangeListener interface:
http://docs.oracle.com/javase/1.4.2/docs/api/java/beans/PropertyChangeListener.html
bean properties can indeed be bound and watched in this manner. In javafx 2.0 Oracle added some really advanced mechanisms for doing this between properties and UI elements and I really hope this can be branched into the core API and somehow become available for Android devs. If JavaFX 2.0 is too late to the game we may get some of the more modern paradigm shifts in the core at least so situations like this can be implemented in a simple and rational way.
I have been trying to find a way to incorporate something similar to Closure in Java 1.6 since I'm developing for Android.
What I want (in a perfect world) I have a class, we will call it "Item".
I then have an arrayList of these.
ArrayList<Item> items = new ArrayList<item>;
In each one of them items.get(x) I want to save a block of code that will be executed when called. This block of code needs to take place in the scope of the class housing the ArrayList items.
My only, half brained idea, would be to create the methods in the class that housed "items" and save the name of the function in each of the "item" instances, then use reflection to call those methods....
I'm pretty doubtful that this could be possible, but this is the place I will find an answer either way.
Thanks ahead of time for any help.
What you need is an interface like
interface Closure{
public void exec();
}
and create an anonymous class for each "closure" code you want
Closure closure = new Closure() {
public void exec(){
// code here
}
}
I new to java so bear with me if this is a ridiculously simple question but I am curious about this method call which has {code} being taken in - see code below for an example in the method addSelectionListener. What is the purpose of this? I have been looking through docs for an explaination but cant seem to find what this practice is called never mind any useful information.
setStatusLine.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
String message = "I would like to say hello to you.";
if (pressed) {
message = "Thank you for using me";
}
setStatusLine(message);
pressed = !pressed;
}
});
Thanks for any help or insights that can be offered
this is an Anonymous Class, or Anonymous inner class. If you google for that you will find some tutorials/examples. Sun has some docs too.
As the other contributors already said: It is an Anonymous Class
You could have created a new class named MyClass in a new file called McClass.java looking like that:
class MyClass extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
<your code that's being executed whenever the widget is being selected>
}
}
Then you could have changed the first line like that:
setStatusLine.addSelectionListener(new MyClass());
See? Now you have an "explicit" class with just one function. Often that is too much overhead and would clutter your design.
Does that help?
The method addSelectionListener receives a SelectionListener instance. It doesn't receive "code". The confusing thing is the use of new <class/interface name>(){...}. This construct is used for anonymous inner classes. In fact what the code above does is extending the SelectionAdapter class, overriding its widgetSelected method, creating an instance of the new class and passing it to addSelectionListener().
Usage of anonymous inner classes is common with listeners, where we create a new class, to be used in one specific place. Therefore we don't give it a name, and we prefer implementing it directly in the context where it is being used.
There is not a method call in fact...
This code set a selection listener on the setStatusLine component.
An equivalent of this code could be
public class X implements SelectionListener{
//In the constructor or an other method.
setStatusLine.addSelectionListener(this);
public void widgetSelected(SelectionEvent e) {
String message = "I would like to say hello to you.";
if (pressed) {
message = "Thank you for using me";
}
setStatusLine(message);
pressed = !pressed;
}
}
It took me some time to understand Anonymous Inner classes. The basic things to remember are:
They are just like parameters, except instead of passing in an primitive or Object you pass in a class that implements an Interface/extends a class (yes they also work with interfaces) depending on method parameter.
They are anonymous, so "disappear" right after the method has popped off the stack.
}); is a dead give-away for an anonymous inner class.
They often pop-up in user interfaces for listener events
They save clutter in your code, but also make it harder to read.
For full punishment read the JLS: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.9.5
If you are interested in knowing the nitty gritty about such things, reading the SCJP book and doing the exam is good or you can study the JLS. It won't learn you how to code, but it will help you understand how Java, and in some way, many other OO languages work.
I have the code of a simple game, where an AgentInterface must be implemented in order to create an agent controller for one of the characters in the game. GameState is a class the implements GameStateInterface, and an object that implements this interface can be passed to the agent, so the agent can read and analyze the data from game state, and the agent must return the appropriate action (returned as an int) that the character should take.
This is the AgentInterface that agents must implement:
public interface AgentInterface {
// the return value specifies the direction of the joystick
public int action(GameStateInterface gs);
}
Running the game with an agent called MyAgent:
GameState gs = new GameState();
AgentInterface agent = new MyAgent();
while (true) {
// more code here
int bestAction = agent.action(gs)
// more code here
}
But, there is some information in GameState that the agent should NOT be able to access, since that would be cheating for the controller. But, doing a cast conversion from GameStateInterface to GameState would allow the agent to access information that is not defined in the GameStateInterface, like this:
public MyAgent implements AgentInterface {
public int action(GameStateInterface gs) {
int nLives = ((GameState) gs).nLivesRemaining; // IS IT POSSIBLE TO DENY/PREVENT THIS CAST??
// Do more stuff here
return BestAction;
}
}
My question would be, is it possible to block a cast conversion? I know polymorphism is one of the main features of Java and Object-Oriented Programming Languages, but in cases like this I would like to avoid cast conversions.
I know this can be solved in many other ways, but I was curious to know if it is possible to do this.
Thanks in advance.
As far as I know, it's not possible to intercept a typecast and deny it (say, by throwing a ClassCastException).
But instead of trying to deny the typecase, you can simply use the Proxy pattern to control access to the actual GameState object. Just implement a proxy class, which only implements the GameStateInterface and let it forward all method calls to the GameState object. Now, instead of passing the actual GameState object reference to the action method, you pass it wrapped by an instance of your proxy class.
In general, you can't prevent an object from being cast in Java. The code that receives a reference to your GameState will be able to call any non-private, non-protected method on that object. Even if you could prevent casting, it could still use reflection.
If the Agent code is under your control, just keep things simple and don't cast. If others write Agent classes, you could create a proxy class which takes a GameState object and only implements the methods of GameStateInterface.
class GameStateProxy implements GameStateInterface {
private GameStateInterface state;
public GameStateProxy(GameState state) {
this.state = state;
}
public int someMethodInGameStateInterface(int x) {
return state.someMethodInGameStateInterface(x);
}
// other methods ...
}
Then you could create a proxy and pass it like this:
GameStateInterface proxy = new GameStateProxy(gameState);
int bestAction = agent.action(proxy);
The code that receives a GameStateProxy would only have access to the methods in GameStateInterface.
It's not possible to block a cast. However, you could define your game state in such a way that it can only be built from a specific place. One thing that comes to mind would be a private inner class implementing the interface, or a factory returning a private inner class instance
The answer is simply "don't cast to GameState in your Agent code".
Alternatively, you can declare the GameState stuff as private. Or if you need to access it from a select few other classes, declare it as package-protected.
If you are concerned about the game state being changed by an agent, then create a bean copy of the state and pass that to the agent, rather than the real GameState object.
Prohibiting a cast doesn't sound possible (it is probably a unblockable JVM language spec feature), or I have never heard of it.
I was implementing a secured read only object. If you create a read only interface (no setters) you still can typecast and access methods of pure object. Eg Interface have only a get and the child of this Interface have the set. If you cast the object to the interface, you only have the get. BUT you still can typecast this object and access everything :(
To avoid that, you can create a composite that will be owned ONLY by the creator of the class. Here is an example :
public class ItemReadOnly {
private String m_name;
private ItemReadOnly(String name){
m_name = name;
}
public String getName(){
return m_name;
}
private void setName(String name){
m_name = name;
}
public static Item createItem(String name){
return new Item(new ItemReadOnly(name));
}
private static class Item {
private ItemReadOnly m_readOnlyInstance;
public Item(ItemReadOnly readOnlyInstance){
m_readOnlyInstance = readOnlyInstance;
}
public void setName(String name){
m_readOnlyInstance.setName(name);
}
public String getName(){
return m_readOnlyInstance.getName();
}
public ItemReadOnly getReadOnlyInstance(){
return m_readOnlyInstance;
}
}
}
This way, you type :
Item item = ItemReadOnly.createItem(name);
So he have the access of Item object (inner class can access private methods :)) Then if you want to give read only access to this item :
ItemReadOnly readOnly = item.getReadOnlyInstance();
Now, it's absolutely NOT possible to typecast because they are not of the same type at all!
Hope this can help someone!
(I'll like if you mention source :P)
What we do is give out a jar with "Stubs" that you can compile against but it contains no implementation. When the actual product runs, we replace the stubs with a real jar.
But then in our case, we control where it runs.
In our case, also, we do exactly what you are asking. Any class has to request access to other classes (at runtime). I believe that's all custom implementation though and I'm not sure it will run on any JVM.
You can try to find/request/whatever the source code for the stuff I'm working on. There is a reference implementation available if you say you are interested in developing for cable boxes you might be able to get it. It's called the "tru2way" or "OCAP" reference stack implementation and I think the project is available on the java site somewhere. Might take a bit of googling--and I'm fairly sure you'll find it's all done in a special class loader or SecurityManager.
EDIT: I think I may be wrong. What we do is create "permissions" with the security manager based on the name of the class being accessed. When a thread tries to call a method on the class, we test it's permissions first (we write the code inside the "protected" class) and if the current thread does not have the permission identified by the name of the class, it throws an exception.
Same effect as you are after, but slower and more verbose. But then we have to prevent kids from watching pr0n.
Edit 2: (Sorry!!)
Looking at permission descriptions like this makes me believe it must be at least partially possible:
This grants code permission to query a class for its public, protected, default (package) access, and private fields and/or methods. Although the code would have access to the private and protected field and method names, it would not have access to the private/protected field data and would not be able to invoke any private methods. Nevertheless, malicious code may use this information to better aim an attack. Additionally, it may invoke any public methods and/or access public fields in the class. This could be dangerous if the code would normally not be able to invoke those methods and/or access the fields because it can't cast the object to the class/interface with those methods and fields.
Otherwise how could applets be prevented from instantiating and accessing arbitrary JVM classes? It's possible that the "Dangerous" paths are all blocked the same way we block our stuff--by reading checking permissions every time they are called--but that quote above makes it seem like there is more available and most classes are completely blocked by default.
This has interested me for a while but I never really looked into it.
One can only cast to an accessible type. By making GameState private, package-protected, or protected, you can restrict who can cast to it.
If you are running untrusted code, be sure to install a security manager, as reflection may be used to circumvent access modifiers in its absensce (c.f. Field.setAccessible)
Nope, there is no way of doing this.
Best wishes,
Fabian
I don't know if what you're describing is possible in Java. In other languages you can overload typecast operators and have them throw an exception or something, but this is not possible in Java. Your best bet is probably to do it in one of the "many other ways" you talked about.