I've always wanted to write a simple world in Java, but which I could then run the 'world' and then add new objects (that didn't exist at the time the world started running) at a later date (to simulate/observe different behaviours between future objects).
The problem is that I don't want to ever stop or restart the world once it's started, I want it to run for a week without having to recompile it, but have the ability to drop in objects and redo/rewrite/delete/create/mutate them over time.
The world could be as simple as a 10 x 10 array of x/y 'locations' (think chessboard), but I guess would need some kind of ticktimer process to monitor objects and give each one (if any) a chance to 'act' (if they want to).
Example: I code up World.java on Monday and leave it running. Then on Tuesday I write a new class called Rock.java (that doesn't move). I then drop it (somehow) into this already running world (which just drops it someplace random in the 10x10 array and never moves).
Then on Wednesday I create a new class called Cat.java and drop that into the world, again placed randomly, but this new object can move around the world (over some unit of time), then on Thursday i write a class called Dog.java which also moves around but can 'act' on another object if it's in the neighbour location and vice versa.
Here's the thing. I don't know what kinda of structure/design I would need to code the actual world class to know how to detect/load/track future objects.
So, any ideas on how you would do something like this?
I don't know if there is a pattern/strategy for a problem like this, but this is how I would approach it:
I would have all of these different classes that you are planning to make would have to be objectsof some common class(maybe a WorldObject class) and then put their differentiating features in a separate configuration files.
Creation
When your program is running, it would routinely check that configuration folder for new items. If it sees that a new config file exists (say Cat.config), then it would create a new WorldObject object and give it features that it reads from the Cat.config file and drops that new object into the world.
Mutation
If your program detects that one of these item's configuration file has changed, then it find that object in the World, edit its features and then redisplay it.
Deletion
When the program looks in the folder and sees that the config file does not exist anymore, then it deletes the object from the World and checks how that affects all the other objects.
I wouldn't bet too much on the JVM itself running forever. There are too many ways this could fail (computer trouble, unexepected out-of-memory, permgen problems due to repeated classloading).
Instead I'd design a system that can reliably persist the state of each object involved (simplest approach: make each object serializable, but that would not really solve versioning problems).
So as the first step, I'd simply implement some nice classloader-magic to allow jars to be "dropped" into the world simulation which will be loaded dynamically. But once you reach a point where that no longer works (because you need to modify the World itself, or need to do incompatible changes to some object), then you could persist the state, switch out the libraries for new versions and reload the state.
Being able to persist the state also allows you to easily produce test scenarios or replay scenarios with different parameters.
Have a look at OSGi - this framework allows installing and removing packages at runtime.
The framework is a container for so called bundles, java libraries with some extra configuration data in the jars manifest file.
You could install a "world" bundle and keep it running. Then, after a while, install a bundle that contributes rocks or sand to the world. If you don't like it anymore, disable it. If you need other rocks, install an updated version of the very same bundle and activate it.
And with OSGi, you can keep the world spinning and moving around the sun.
The reference implementation is equinox
BTW: "I don't know what kinda of structure/design" - at least you need to define an interface for a "geolocatable object", otherwise you won't be able to place and display it. But for the "world", it really maybe enough to know, that "there is something at coordinates x/y/z" and for the world viewer, that this "something" has a method to "display itself".
If you only care about adding classes (and not modifying) here is what I'd do:
there is an interface Entity with all business methods you need (insertIntoWorld(), isMovable(), getName(), getIcon() etc)
there is a specific package where entities reside
there is a scheduled job in your application which every 30 seconds lists the class files of the package
keep track of the classes and for any new class attempt to load class and cast to Entity
for any newlly loaded Entity create a new instance and call it's insertIntoWorld().
You could also skip the scheduler and automatic discovery thing and have a UI control in the World where from you could specify the classname to be loaded.
Some problems:
you cannot easily update an Entity. You'll most probably need to do some classloader magic
you cannot extend the Entity interface to add new business bethod, so you are bound to the contract you initially started your application with
Too long explanation for too simple problem.
By other words you just want to perform dynamic class loading.
First if you somehow know the class name you can load it using Class.forName(). This is the way to get class itself. Then you can instantiate it using Class.newInstance(). If you class has public default constructor it is enough. For more details read about reflection API.
But how to pass the name of new class to program that is already running?
I'd suggest 2 ways.
Program may perform polling of predefined file. When you wish to deploy new class you have to register it, i.e. write its name into this file. Additionally this class has to be available in classpath of your application.
application may perform polling of (for example) special directory that contains jar files. Once it detects new jar file it may read its content (see JarInputStream), then call instantiate new class using ClaasLoader.defineClass(), then call newInstane() etc.
What you're basically creating here is called an application container. Fortunately there's no need to reinvent the wheel, there are already great pieces of software out there that are designed to stay running for long periods of time executing code that can change over time. My advice would be to pick your IDE first, and that will lead you someways to what app container you should use (some are better integrated than others).
You will need a persistence layer, the JVM is reliable but eventually someone will trip over the power cord and wipe your world out. Again with JPA et al. there's no need to reinvent the wheel here either. Hibernate is probably the 'standard', but with your requirements I'd try for something a little more fancy with one of the graph based NoSQL solutions.
what you probably want to have a look at, is the "dynamic object model" pattern/approach. I implemented it some time ago. With it you can create/modify objecttypes at runtime that are kind of templates for objects. Here is a paper that describes the idea:
http://hillside.net/plop/plop2k/proceedings/Riehle/Riehle.pdf
There are more papers but I was not able to post them, because this is my first answer and I dont have enough reputation. But Google is your friend :-)
Related
Scenario
This question may be a question about conventions, but Java might have a built-in way to do this. I'm explaining my problem with a scenario:
We are three people working on a project, and we're all doing different parts, and working on different git branches, all of which will be needed in the end project.
My part of the program runs the TUI (let's call the class Startmenu), which requires to run functions from an instance of the Database class. In my switch cases, I know the future code from the other branch will allow me to simply run db.printElements(), as an example.
Problem
Nevertheless, this is the problem: I cannot define Database db; in the class structure, nor can I assign my Startmenu() constructor to take a Database db as an input such as Startmenu(Database db), because it does not yet exist.
In practice, how do I solve this issue? Currently, I'm commenting out the parts that require parts of the other code, and replace it with poisoned code instead, as a placeholder. This doesn't seem like the best idea.
I know a solution is to create the Database class, with empty functions for those functions I will be needing right now, but this will mess with git instead.
tl; dr: How can I prepare my own files to use code that does not yet exist, which will appear "magically" by other people over time?
All components in your project should have specified an interface to exchange information across layers and other Java components during the design phase.
You can early commit and share these interfaces, so other colleagues can provide their own testing implementations or mock behaviours.
Is there a way to make a collection of class files/objects and then have them used in an interactive main file? So let's say I want to make a program to store information interactively where different classes are designed to hold different information. Then I would have an interactive main file where I made instances of these classes which would collectively hold the information I want stored. And then any changes or anything I do in this interactive main file is then saved.
I understand that this might be a very odd inquiry and maybe some other program might be useful for this. If so, feel free to point me in the right direction.
Here are two solutions that are good for the purpose you mentioned in your comment.
The first one is called Serialization. This let's you save your java object to your hard drive, and retrieve it later.
The second, (and in this case, more preferable option in my opinion), is using a Database.
A database is a compliment to your program, that stores data. You can then use "Queries" to access this data, and update it. Almost every database software is compatible with java.
I would look into MySQL
The reason I think a database would be better for your purpose is that they are already highly optimized, and are designed to have multiple people accessing and writing to them at once. If you wanted just want one person to use this program at a time however, serialization might be easier to implement.
Absolutely! Your main class would use the standard input (perhaps Scanner input = new Scanner(System.in);) and output (System.out.println()). To interact with your other classes, most simply, just put them in the same folder (if you are interested take a look at Java packages). If you have a Dog class in the same folder as your main class, you can freely create Dog objects in your main class. I hope this helps!
As a side note, because you mentioned storing information with different classes, you might be interested in the Java Collections Framework.
I am in charge of maintenance of an old application written in Swing, combined with a CAD-like tool written in Java3D. We are having problems with memory usage. After profiling, this is related to the undo functionality in the application.
All undo functionality is state-based, with a basic concept like this:
public class UndoAction {
private UndoTarget target;
private Object old_data;
private Object new_data;
}
Code to create these UndoActions is basically littered throughout the application. Because there is no distinction between modifications of new objects, modifications of existing objects and modifications of subtrees, the following happens:
What happens is a single action is the following:
Create a new object A.
Modify field foo of the object. A new UndoAction is placed on the stack, which contains foo_old and foo_new.
Modify field bar of the object. A new UndoAction is placed on the stack, which contains bar_old and bar_new.
Execute B.setField(A). A new UndoAction is placed on the stack, which contains field_old and field_new (== A).
There is no granularity or any control over this at all. This does not help maintainability at all.
I want to refactor this system so it becomes maintainable and memory-friendly. Unfortunately, implementing the Undo system using the Command pattern is not possible; the actions are too impacting to revert. I want to implement the following:
Use annotations to provide "Undo demarcation". #Undoable() would mark a method as generating an UndoAction which is put on the stack. This can be parametrised just like transactions: REQUIRE, NEST, JOIN... The full object graph is cloned upon entering the Undoable method.
When a Transaction (=method) finishes, an algorithm should compare the new state with the old state and save a diff.
To implement this, we can use AOP. This allows us to keep the core code very clean.
An now, my question:
Do any of the above 3 functionalities already exist in Java? I can imagine I am not the first to wrestle with state-based undo and the problems linked to it (Undo demarcation, state compare, ...)
After this question has been open for quite some time, it seems the question is: "No, no such framework already exists."
As a guide for other people, I am looking into Eclipse Modeling Framework and the EMF.Edit framework. In this framework, you define the model in a descriptor language, and the framework handles the model and any manipulations for you. This automatically results in Actions and Undo/Redo being created.
For reference, one other framework that may serve as a model (if not a solution) is UndoManager, which supports a limited number of edits. It's part of the javax.swing.undo package, one of several core Text Component Features.
I'm developing a swing based application where I'm using many FileDialogs? So I say why not to make just one FileDialog object instead all of these instances and use it in the whole project? Is this a good assumption? does this have any performance improvement?
Thanks
This is a great example of a use case where application performance doesn't really matter and the question actually falls into the premature optimization class of problem solving. Why? Using FileDialog means that you are interacting with the user who, even if skilled beyond skilled with shortcut key Kung Fu, will be many orders of magnitude slower than the application. How many FileDialogs could a speedy user open, use and close in one minute? Say a dozen. You should not need to care about a dozen objects coming and going in one minute. Shouldn't even appear on your radar. Use your energies elsewhere. In fact, you should create a new object every time and avoid any caching headaches.
I would make a static FileDialog class that generates a new instance of the FileDialog each time a new one needs open rather than sharing a Singleton instance across the application.
That'll save you the headache of trying to figure out if you're reading the correct path from the dialog box or if somebody has opened the dialog and picked a new path and now you're referencing that new path rather than the originally selected path, etc...
Why implement is as a Singleton? Can you actually verify that displaying two file dialogs will never occur?
Better to have it as a regular class; you don't want to build in limitations which could become pain points later.
It isn't like your application is going to be critically overloaded by millions of calls to the file dialog, and who knows, perhaps someday it will be the right solution to have two file dialogs. Even if you don't display them both at the same time, perhaps holding the history in a "source" dialog and having a separate history in the "destination" dialog would be a blessing in a file transfer program.
Forget performance/speedyness. It doesn't matter here. Semantics matter. Reusing the same file dialog may give you things for free. Will the dialog start in the same directory every time? It will if it is the same instance. If you are creating new dialogs you will have to set startup dir your self.
Also why make it impossible to create more than one instance? Just make an instance member in your frame and be done with it.
I'm writing a small application in RCP to wrap around the business logic in another (non-RCP) simulation library. I can access and use the library fine from any of my plugins, but I don't know where I should put the instance of the Simulation library so that, say, one of the command handlers can make calls to it.
From reading the docs it sounds like I should be storing 'global' information like this in the workbench - but I still don't really understand how to do that.
Help?
First, the business layer (BL) can and should reside in its' own plugin. That will provide decent decoupling between the layers.
Second, you should carefully decide what the interface should be and which classes are exposed. Ideally, you should mostly expose interfaces and data objects.
Finally, decide how the "hand shake" works. E.g., how to obtain the initial interface to the BL. Since it is a Plugin, it could have an Activator which loads it. You could add a method in the activator which returns the BL interface.
If you are looking for something more decoupled, you could create an extension point or deploy the BL as an OSGi service, but that's a bit of an overkill for you need.
If I understand you correctly, I see two ways:
Store the instance in the model plug-in itself, using ‘SimulationFactory.getInstance(String myAppId)‘. The passed String is a constant in you app that is always used, when obtaining the reference.
Define a new class e.g. GlobalAccess in you app that is initilized with an instance of your model and has some getter (whether you use a single instance again or only provide public static methods is a matter of taste).
The seocond way is similar to some classes in eclipse like platfom or platformui, where you can obtain initial references and navigate through the workbench.
edit
i just found a tutorial that might help you:
Passing Data between Plug-ins