keep track of an instance attributes changes - java

We are working on a multi process projects which use RMI for RPCs.
The problem that we are facing is that the main object which must be passed between processes is very big (when serialized), and this dropped the performance of the code dramatically.
Since, none of the processes change the whole object and only alter small parts of it, we decided to just pass "the modifications" through RMI.
but I found no proper way to implement such concept. The first idea was to keep track of all changes of the main instance. But this seems not easy according to this.
I need a way which we can:
develop fast
performs fast
any suggestion?

Just make this 'main object' a remote object that implements a remote interface, and export it, instead of serializing it backwards and forwards.

I think the best way is to customize your serialization so you will be able to send only the changes. you can do it by implementing private method of
private void writeObject(java.io.ObjectOutputStream stream) and of course also readObject from the other side. well, what you should do in this functions?
I suggest you will manage a bitmap of all the members that were changed and only send them in the serialization, just change the unchanged members to null send the object in serialization and than return there values. in the other side read the bitmap and than you will know how to

First time you need to pass the whole object.
Use PropertyChangeListener on the object, this would generate an PropertyChangeEvent.
You can pass the PropertyChangeEvent around. It has the getSource(), by which you can identify the object. If this is not enough, if you need IOR or any other sort of reference, create a wrapper and sent it across..
-Maddy

Have a look to http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html
public class Test {
PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
pcs.firePropertyChange("name", oldName, name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
int oldAge = this.age;
this.age = age;
pcs.firePropertyChange("age", oldAge, age);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
public Test(){
}
public static void main (String[] args){
Test myTestObject = new Test();
myTestObject.addPropertyChangeListener(new MyPropertyChangeListener());
myTestObject.setAge(12);
myTestObject.setName("Rick");
myTestObject.setName("Andrew");
}
private static class MyPropertyChangeListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent event) {
String clazz = event.getSource().getClass().getName();
System.out.println(clazz+"::"+event.getPropertyName()+" changed from "+event.getOldValue()+" to "+event.getNewValue());
}
}
}
This is a simple example but using this approach you can create different PropertyChangeListeners and provide different logic inside theirs method propertyChange.
Also is possible to fire only the changes over a small set of attributes and not over all of them (not storing the oldValue and not firing the firePropertyChange method of PropertyChangeSupport).
Of course that you can use AOP, but perhaps you are looking for a solution like presented above. I hope this helps.

Related

How to fix Mass Assignment: Insecure Binder Configuration (API Abuse, Structural) in java

I have a Controller class with the below two methods for finding a doctors (context changed). Getting the
Mass Assignment: Insecure Binder Configuration (API Abuse, Structural) error on both methods.
#Controller
#RequestMapping(value = "/findDocSearch")
public class Controller {
#Autowired
private IFindDocService findDocService;
#RequestMapping(value = "/byName", method = RequestMethod.GET)
#ResponseBody
public List<FindDocDTO> findDocByName(FindDocBean bean) {
return findDocService.retrieveDocByName(bean.getName());
}
#RequestMapping(value = "/byLoc", method = RequestMethod.GET)
#ResponseBody
public List<FindDocDTO> findDocByLocation(FindDocBean bean) {
return findDocService.retrieveDocByZipCode(bean.getZipcode(),
bean.getDistance());
}
}
and my Bean is :
public class FindDocBean implements Serializable {
private static final long serialVersionUID = -1212xxxL;
private String name;
private String zipcode;
private int distance;
#Override
public String toString() {
return String.format("FindDocBean[name: %s, zipcode:%s, distance:%s]",
name, zipcode, distance);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
As per all the suggestions found so far, they are suggesting to restrict the bean with required parameters only by something like below :
final String[] DISALLOWED_FIELDS = new String[]{"bean.name", "bean.zipcode", };
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(DISALLOWED_FIELDS);
But my problem is all the 3 parameters of the bean will be used in either of the method supplied on Controller.
Can someone please suggest some solution for this. Thanks in advance.
InitBinder can be used for methods. You can try this.
#InitBinder("findDocByName")
public void initBinderByName(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","zipcode"});
}
#InitBinder("findDocByLocation")
public void initBinderByZipCode(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","name"});
}
i was facing same issue, then i added below code in same rest controller class:
#InitBinder
public void populateCustomerRequest(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{});
}
now its working fine for me and mass assignment issue was fixed.
Simple question - how your mapper can instantionate the bean? Here is answer / example. You can pass that data by query parameter, or in header. However that would be strange. Better is to have that methods with #QueryParam providing location, or name. That way it will be easier to protect your application.
As a side note, query has limited length, so if your search form is big and strange, #POST can be good idea, and that way you can pass all the data. For this, simple example that would be overkill.
This looks like an unfortunate false positive. The rule behind this error is made to avoid that properties present in an object but not intended to be (unvalidated) user input are accidentally populated from a web request. An example would be a POST request creating a resource. If the request handler takes the full resource object and fills only missing properties an malicious user could populate fields that she shouldn't be able to edit.
This case however does not match the scheme. You just use the same mechanism to capture your different arguments. Additionally populated properties will not even be read. In
GET http://yourhost/findDocSearch/byName?name=Abuse&zipCode=11111
the additional zipCode would just be ignored. Therefore the assumed risk is not present here.
To fix the warning, you could mark it as a false positive (if this is possible inside your setup). If that is not possible you could also just map the query parameters to method arguments directly. As you only have limited parameters that should not harm too much. If this is also no option you probably need to figure out the exact algorithm your code analysis uses to figure out what checks it will recognize. Unfortunately most scanners are only able to discover a limited set of ways to do input validation.

Is it possible to build an object like this at runtime in java?

As the title says....
I want to build a POJO with four field variables and at certain runtime events create an instance of this POJO with access to possibly maybe two or three of the fields.
public class Category implements Serializable {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Lets say I create a new Category object but I only want to be able to have access to the name field during runtime. Is there a design pattern I can use to achieve this? I thought about the strategy pattern and looked at the builder but I am still confused if I can do this in java.
Basically the overall goal is to grab an object from a database and return it as a JSON response in jax rs. But sometimes I dont want a complete object returned but only lets say halve of the object to be accessible at during certain runtime events. My apologies if this seems like a dumb question but I know what I want to do but just don't know the best way.
I have the same problem with you, and my project was used springmvc,and the json tool is jackson.With the problem solved, I just use #JsonIgnore.For more details,just read jackson-how-to-prevent-field-serialization
So someone correct me if I am wrong or see a better option than this...with alot of objects this can be alot of extra code for serialization and deserialization...Jackson Provisions is what I need. I can use the annotation #JsonView(DummyClass.class) on the field variable. I will accept this a the best answer in a day or two unless someone else posts a better response.
// View definitions:
class Views {
static class Public { }
static class ExtendedPublic extends PublicView { }
static class Internal extends ExtendedPublicView { }
}
public class Bean {
// Name is public
#JsonView(Views.Public.class) String name;
// Address semi-public
#JsonView(Views.ExtendPublic.class) Address address;
// SSN only for internal usage
#JsonView(Views.Internal.class) SocialSecNumber ssn;
}
With such view definitions, serialization would be done like so:
// short-cut:
objectMapper.writeValueUsingView(out, beanInstance, ViewsPublic.class);
// or fully exploded:
objectMapper.getSerializationConfig().setSerializationView(Views.Public.class);
// (note: can also pre-construct config object with 'mapper.copySerializationConfig'; reuse)
objectMapper.writeValue(out, beanInstance); // will use active view set via Config
// or, starting with 1.5, more convenient (ObjectWriter is reusable too)
objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);
This information was pulled from http://wiki.fasterxml.com/JacksonJsonViews
with jackson 2.3, I can do this with JAX-RS
public class Resource {
#JsonView(Views.Public.class)
#GET
#Produces(MediaType.APPLICATION_JSON )
public List<Object> getElements() {
...
return someResultList;
}
}

Framework for combining components

I'm trying to find a framework, or a nice way of implementing a way combining various components, similar to an electronics kit. This is so that it can be wired together using xml (e.g. Spring). I want the users to be able to string together different components without having to worry about Java.
The set up I'm thinking of would have something like the following:
public interface Input<T> {
public T getValue();
}
public interface Output<T> {
public void setValue(T value);
}
public class Wire<T> implements Input<T>, Output<T> {
private T value;
public T getValue() { return value; }
public void setValue(T value) { this.value = value ; };
}
And then components would be something like
public interface Component {
public void evaluate();
}
public class Multiplier implements Component {
private Input<Double> inA;
private Input<Double> inB;
private Output<Double> out;
public Multiplier(Input<Double> inA, Input<Double> inB, Output<Double> out) {
this.inA = inA;
this.inB = inB;
this.out = out;
}
public void evaluate() {
out.setValue(inA.getValue() * inB.getValue());
}
}
main() {
Wire inA = new Wire();
Wire squareOut = new Wire();
Component squarer = new Multiplier(inA, inA, output)
}
So you could tie outputs of one component into the input of another. I've toyed with the idea of the Wires knowing about what outputs they're connected to, so that they can call evaluate on their components... but I think it might be easier to keep a separate "clock" so that circular dependencies can be controlled.
It's not hard to implement, I'd just rather use a public library if there is one already out there. I've struggled to find one.
Any advice about implementing something similar, or what to do instead would be really helpful.
You are talking about Dependency Injection Framework.
Look at Spring, Google Guice or PicoContainer.

Sync object with values in GUI using Metawidget

I'm using Metawidget to automatically see/edit values in objects in the GUI. I'm able to bind the object's initial values, and see them in their respective GUI components. However, when I change the values in the GUI, these changes are not sync'ed back to the object. This is more or less documented here (deprecated) and here.
Here is my business object:
public static class Person {
private String mName;
public String getName() { return this.mName; }
public void setName( String name ) { this.mName = name; }
#UiAction
public void showPersonObject() {
JOptionPane.showMessageDialog(frame, this.mName);
}
#UiAction
public void bind() {
metawidget.getWidgetProcessor(
BeansBindingProcessor.class)
.save( metawidget );
}
}
Here is my main method, where metawidget is configured:
public static void main( String[] args ) {
// Person
Person person = new Person();
person.setName("A cool name");
// Metawidget
metawidget = new SwingMetawidget();
metawidget.setInspector( new CompositeInspector(
new CompositeInspectorConfig().setInspectors(
new PropertyTypeInspector(),
new MetawidgetAnnotationInspector(),
new BeanValidationInspector())));
metawidget.addWidgetProcessor(
new BeansBindingProcessor(
new BeansBindingProcessorConfig().setUpdateStrategy(
UpdateStrategy.READ_WRITE )) );
metawidget.setToInspect( person );
// Create Frame
...
}
In the documentation it is said that:
If set to READ or READ_WRITE (the default is READ_ONCE), the object
being inspected must provide PropertyChangeSupport. If set to
READ_WRITE, updates to the UI are automatically sync'ed back to the
setToInspect, otherwise the client must manually call save:
myMetawidget.getWidgetProcessor( BeansBindingProcessor.class ).save( myMetawidget )
I've tried setting the UpdateStrategy to READ and/or READ_WRITE, and/or calling save() on BeansBindingProcessor. I've also tried to provide PropertyChangeSupport to the Person object (I think its refering to this), which is the same as adding the following code:
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(listener);
}
public void setName( String name ) {
String oldName = this.mName;
this.mName = name;
this.pcs.firePropertyChange("name", oldName, mName);
}
However, the Person object always maintains the original values.
Thanks in advance.
Well, I solved the problem. There is a "rogue" version of beansbinding.jar on the internet, that's why binding wasn't working. I used the version distributed with Metawidget examples, and now everything works fine.
This problem is reported here.
Sorry for the confusion regarding the 'rogue' version of BeansBinding. I have updated the Metawidget documentation to save frustration for others in future.

using eclipse template to create test cases

Often do I find myself creating the same unit tests methods to getters\setters, c'tors and Object methods (hashCode, equals and toString).
What I'm trying to achieve, with the help of Eclipse IDE, is automation of this procedure.
consider this example:
public Class Person {
private String id;
private String name;
public Person(String id, String name){
this.id = id;
this.name = name;
}
public String getId() { return id; }
public void setId(String id) {
this.id = id;
}
public String getName() { return name; }
public void setName(String name) {
this.name = name;
}
#override
public int hashCode(){ ... }
public boolean equals(Person other){ ... }
public String toString(){ ... }
/* this class may implement other logic which is irrelevant for the sake of question */
}
The unit test class will look something like this:
public class PersonTest extends TestCase
{
#override
public void setup() {
Person p1 = new Person("1","Dave");
Person p2 = new Person("2","David");
}
#override
public void tearDown() {
Person p1 = null;
Person p2 = null;
}
public void testGetId() {
p1.setId("11");
assertEquals("Incorrect ID: ", "11", p1.getId());
}
public void testGetName() { /* same as above */ }
public void testEquals_NotEquals() { /* verify that differently initialized instances are not equals */ }
public void testEquals_Equals() { /* verify that an object is equals to itself*/ }
public void testHashCode_Valid() { /* verify that an object has the same hashcode as a similar object*/ }
public void testHashCode_NotValid() { /* verify that different objects has different hashcodes*/ }
public void testToString() { /* verify that all properties exist in the output*/ }
}
This skeleton is similar to the vast majority of classes created.
can it be automated with Eclipse?
Have a look at Fast Code. It is an eclipse plugin that provides very nice feature of templating stuff which is what you seem to be looking for. On the documentation page look for Create Unit Test section.
A very useful feature of this plugin is to create unit tests automatically. Unit tests can be of type Junit 3, Junit 4 or TestNG. For Junit 4 or TestNG tests, appropriate annotations will be automatically added. One needs to configure it just once.
Unit tests are meant to show that an Object's behaviour is conforming to it's expected behaviour. They are not meant to make sure that the Java language is working correctly.
What you have here is a fancy data structure, with no behaviour. In that case every assignment is mediated by a method call, and every dereference is also mediated by a method call. Since Object Oriented programming is "data + behaviour" = objects, and this code lacks behaviour, it's a candidate for being called non-object-oriented code.
Sometimes Java uses non-object-oriented classes to facilitate transfer of information. The class guarantees that all information gets transferred as one unit when doing serialization. So having such a class isn't an indicator that the code is wrong; however, if you run into too many classes like this then something is very wrong.
One key element of testing is that it's not really a test if the test cannot fail. If the test cannot fail, it's just busywork. Assuming that one of these fields cannot be null then the setter might look like
public void setName(String name) {
if (name == null) throw new IllegalArgumentException("name cannot be null");
this.name = name;
}
And then you have something to test. Otherwise, your just checking to see if the assignment operator failed. As an aside, if the assignment operator failed, then I'd wager that the JVM is going to come down pretty hard sooner (rather than later) and you can't trust your tests to report correctly either.

Categories