I'd like to add persistence to my Swing-based application; and this is the first time that I'm doing something like that.
I know how to use Java serialization APIs (though I'm using xstream instead), I know that JComponent's are serializable, but I'm interested in more architectural considerations: how an application should be designed so that making it persistent becomes easy; etc.
I'd be happy to see any sources with in-depth consideration of these issues, though I'd be also happy to hear some best practices explicitly :)
You should use a model-view-controller approach. You only serialize the model, not the view. The view should be populated from the model. Serializing Swing components is anyways not recommended at all:
While Swing components do implement the Serializable interface, they are not portable between different versions of the Java Virtual Machine
Looking at what you have, you should have some classes that are your model and have only data. These classes will be serialized using XStream somewhere. Your Swing Classes then have methods to receive these model classes and populate the fields and editors. You can then extend the UI, for example, without having to change the class, adding more funcionality, or provide different views for the same data set.
To make it fancier, the Swing Component should not store and load the model, but you should have a controller interface that you pass to the swing component to perform these operations. This way, you can unit test better and you decouple the storage logic from the view logic.
If XStream is correctly configured, and if you are careful about the model and the fields, it should be possible to add more fields to your model classes without breaking backwards compatibility.
I don't recommend using Java Serialization anyways, as it is not a good practice to use it for storage. Java Serialization excels at Remote Method Invocation. It is relatively fragile when the model classes change..
And the javadoc says (for instance on JComponent): As of 1.4, support for long term storage of all JavaBeansTM has been added to the java.beans package. Please see XMLEncoder.
So see XMLEncoder.
From architectural point of vue, this serialization work best with beans, collections, and the notion of default value. On beans, it save only properties beans with a different value than default value. (sorry for my english)
You can configure that as you want.
Related
So my company decided that it needs some kind of system / service that has the following properties:
Uses Java and Spring-Boot as a Back-End
Has an Angular Front-End for and Admin UI
Uses mongoDB for persistence
The system should include following functionality:
Users (Experts, Data-Engineers, Developers) should be able to define the data model including dynamic types having a set of properties and relationships via an Admin UI.
The system should support multi-tenancy, meaning that it should integrate multiple clients from different tenants.
It is important, that different clients have different projections of the data when reading, meaning that not all clients are allowed to read all the properties of an entity, but are restricted to what has been configured for them.
There must be some kind of validation for the properties (e.g. if it is of type string it must follow a common pattern, if it is of type enum only certain values are accepted)
I did some research and came to the conclusion that there are certain drawbacks with this proposed solution being:
using java for handling dynamic types
favoring abstract code instead of an explicit data model violating the "use before re-use principle"
I also fear, that we are re-inventing the wheel - meaning that there might be existing solutions for dynamically defining a data model.
I have to take these decisions as a given and try to find a way to still use existing implementations as far as possible.
In the end it will adapt a pattern similar to the EAV model. In my opinion there will be almost no possibility to adapt domain specific language and rules, since it aims to be as abstract as possible. It seems to me that it is a clear case of the inner-platform-effect, meaning that it will be result in a system that is
"so customizable as to become a replica, and often a poor replica, of
the software development platform they are using"
Nonetheless I have to deliver some kind of implementation which has to move within this frame.
I don't want to re-invent the wheel and create a proprietary solution - so I am thinking about using at least some standard for solving this issue, as for example generating json-schema from the user configuration instead of inventing my own data structures and validation logic.
Has anyone experience with json-schema and dialects or can point me to any other solution that I can adapt to make my life easier without having to come up with a home-made solution?
PS: I am not sure if these design questions belong to SO or any other place, so please let me know if you think I misused SO
I've been reading a lot about package-by-feature naming convention. So I've decided to give it a try in a new project. However, I'm not sure how it should be named my packages that will be used by most of my classes, since I'm using a huge framework, such as Spring and Hibernate, for example.
This is how handle our Spring contexts classes:
And our database access class, the one that manages connections and so on.
I've a draft about this: using a common package for these frameworks, like:
com.company.project.common.spring
com.company.project.common.database
But I'm afraid that this still looks like package-by-layer a bit. :)
How the packages that will be accessed by my feature classes should be created ?
The common recommendation is "package by feature, not layer". What I often do is "package by feature, then layer". I also think that top-level packages should be "feature"-based (functional components, whatever). But I also like to have my layers separated into sub-packages.
From my point of view, framework-related code does not per se constitute "features" (as in "important, high-level aspects of the problem domain"), therefore package-by-feature is does not make much sense here. But still, this is important code and you need an approach to structure it.
I am normally use two approaches:
If I need to extend or augment libraries I'm using, I structure packages parallel to the package structure of the library. For instance if I'd need to implement some new number formatter for Spring, I'll probably name the package com.acme.foo.springframework.format.number, parallel to org.springframework.format.number.
However if I need to implement common base classes for layers of features, this would be probably something like com.acme.foo.common.<layer>. For instance if we have com.acme.foo.<feature>.dataaccess packages for data access layer of some feature, com.acme.foo.common.dataaccess could hold base classes for data access layers of all features.
Both approaches are used in parallel. You just have to decide whether some class is a framework or library extension (can you imagine using it outside this project?) or is it closer to the layers of your project.
Up to now, the com.ibm.jscript.std.FunctionObject does not implement Serializable. In my opinion, when working with server-side JavaScript (SSJS) it would be very beneficial if it could be serialized. Since I'm no Java expert, I'd like to ask if there is a special reason why the FunctionObject does not implement Serializable, while other SSJS objects (like the ObjectObject) do. Will it never be serializable?
I suspect it's because FunctionObject is intended not as an SSJS version of a Java object but more as an SSJS version of a Java static class, so just a set of utility functions and so a single object per NSF. I doubt it will ever be serializable.
In my opinion SSJS is a limbo language for those getting started with XPages and coming from a Domino background. It allows easy access to Formula Language, global objects (like context and database), LotusScript-style Domino Object Model and client-side JavaScript-style libraries (e.g. i18n).
I think the expectation is that if developers are familiar enough with things like serialization and developing using objects, they are probably ready to go down the road of Java classes as managed beans or Data Objects, plus validators, converters, or even a full MVC model. That also leads the way to moving cross-database components and utilities out of the NSF and into an OSGi plugin or extension library. There are more and more examples of that on OpenNTF now.
Back in the days, I have more than once implemented properties and listeners similar to what is provided by JavaFX.
As I always prefer to use widely supported packages rather than something I have invented myself, I feel very tempted to use JavaFX properties in my next project, but before that, I would like to get an answer to the following question.
In software that has nothing to do with GUI, but would benefit from change listeners in order to monitor and control system state, should I still choose the property mechanisms provided by JavaFX, or is there somethin else available that would work for me? ...or am I still in need to implement this mechanism by myself?
Regards,
Fredrik
After using javaFX properties for non UI-related logic for about a year on a commercial product, here is my two cents:
It may not be a good idea to mix UI-related properties and Business-logic-related properties.
It works great if both kind does not have to interact with each other. But problems arise when you start binding UI elements to Business-logic properties. The reason is you will often have busness-logic code running in dedicated threads, and if this thread updates a property that is part of a binding, you will get the following exception:
java.lang.IllegalStateException: Not on FX application thread;
The easy fix then is to move the code block that changes the property value in a
Platform.runLater(...)
call... But then you have some javaFX-framework dependant code in Business-logic code. So if you re-use this code in an Swing application or simply if you want to test it with a JUnit test, you will get errors there too:
java.lang.IllegalStateException: Toolkit not initialized
As you are using Platform.runLater() that requires the JavaFX toolkit to be initialized, at this is not the case in a unit test or a swing/javaee application.
To wrap up, it is possible to use javafx properties for non UI code but it could have non trivial side effects...
JavaFX property mechanisms should work. They were written to support JavaFX GUIs but should work fine for non-gui logic as well - although I don't think there has been widespread usage for that purpose thus far. I can't speak to other competitive frameworks as to which may address your needs better.
When you see the number of classes for property support in JavaFX, it can be a bit daunting, but they tend to hang together quite well and a lot of the classes exist to shield object/primitive impedence mismatches. It is a shame there is not better language support for such features. Programming with an IDE and autocomplete works quite well so that you don't need to type as much. The listeners fold into jdk8 lambda expressions so they can end up quite concise.
The binding and listener frameworks are part of what allows JavaFX controls to be so readily adapted and utilized - they provide hooks into change notifications for every item of the system.
JavaDoc is available. Unfortunately the official documentation on bindings and collections does not do the library justice in thoroughly describing how to use it's feature set. There is a useful article on using the JavaFX properties with POJOs.
The source for beans, binding and property support for JavaFX is not yet public (though it is scheduled to be made public over the next few months).
Use a version of Java later than jdk7u6 and ensure the jfxrt.jar file from the distribution is on your classpath so that you pick up the JavaFX classes. If you are not using any GUI components, you don't need to extend the JavaFX Application class in your program.
Relevant non-GUI packages to consider are:
javafx.beans The package javafx.beans contains the interfaces that define the most generic form of observability.
javafx.beans.binding Characteristics of Bindings
javafx.beans.property The package javafx.beans.property defines read-only properties and writable properties, plus a number of implementations.
javafx.beans.property.adapter (adapts standard pojo beans to JavaFX properties).
javafx.beans.value The package javafx.beans.value contains the two fundamental interfaces ObservableValue and WritableValue and all of its sub-interfaces.
javafx.animation Provides the set of classes for ease of use transition based animations (timing related non-gui portions).
javafx.collections Contains the essential JavaFX collections and collection utilities
javafx.util.converter This package is for standard string converters for JavaFX.
I'm new to the architecture of UIs and in the past I've programmed very simple UIs. Now I'm confronted with a very large domain model. Because I've used different OR-Mappers to store domain objects in a flat data structure I thought about mapping the domain objects to the view-side in a similar way.
Are there any patterns or frameworks that address this problem?
More precisely I want to adapt the domain objects to eclipse RCP views in an easy way.
Thanks in advance
Regarding Eclipse RCP, I'm not aware of any 'frameworks' for this, but at least the JFace ContentProvider mechanism makes it easy to write a layer of re-usable adapters that handles the presentation of your domain classes in JFace viewers.
If you're after some generic (or starting-point) CRUD screens for domain classes, perhaps you can use code-generation, reflection, and/or dynamic proxies for the ContentProvider classes, taking each domain class (or classes) as input. However, this is rarely as simple as it sounds.
What about Metawidget ?
Metawidget is a 'smart User Interface
widget' that populates itself, at
runtime, with UI components to match
the properties of your business
objects.
Metawidget does this without
introducing new technologies. It
inspects your existing back-end
architecture (such as JavaBeans,
existing annotations, existing XML
configuration files) and creates
widgets native to your existing
front-end framework (such as Swing,
Java Server Faces, Struts, Android).
I never tried it myself, but it looks like promising for this kind of mapping.
A more complete framework is Naked Objects, of which I'm a committer and also the lead on a number of sister projects. One of those sister projects is an Eclipse RCP viewer, though it is currently stalled. Feel freed to contact me via my blog if any of this sounds of interest.
-- Dan