XPages: NotSerializableException on DateTime - java

I'm kind of desperate. We have a lot of code, and we also have a lot of variables of which many are inside viewScope and other HashMaps. Every now and then we get the error that some DateTime object cannot be Serialized. I understand the why, no problem there. But which variable? Which element of the HashMap? Since Serialization happens automatically, out of my control, the problem could be anywhere. It could be a DateTime value the code puts into a viewScope variable (I think I checked them all), it could be my own beans' HashMaps, and it could even be lines with column values from a view. I just don't know...
Can anyone point me into the right direction to find out where that #$#%#! exception really occurs? For instance: can the stack trace be more informing about which HashMap it found the problem in, and maybe even which key??
#$#%#! - read: elusive...

One option would be to add a PhaseListener to your application that, in Render Response phase, iterates through all scopes and outputs the key and the output of getClass() for the value. The code could also do the same for the hash maps in the beans.
There are various examples of PhaseListeners on XSnippets.

Related

Zuul filter return value

What is the possible usage of ZuulFilter.run() return value?
All the examples (for instance Spring example) return null.
The official documentation says:
Some arbitrary artifact may be returned. Current implementation ignores it.
So why to have it at all?
I've used this lib in multiple projects and I never thought to look into and stumbled upon this question so I had to look. Just tracing the code in IntelliJ, it does look like the results are pointless.
I'm on zuul-core:1.3.1:
Looking at FilterProcessor, when the routing methods are called to route based on the type, they all call runFilters(sType) which ultimately get the the return Object in question of the implementing IZuulFilter classes. The trail seems to stop here.
I then stopped to looked at their test classes and nothing seems to do anything with the return Object either nor the ZuulFilterResult that wraps it.
I then thought, ok, well maybe there is a way to pass data from one IZuulFilter to another (e.g. from pre to route) but that doesn't seem possible either since FilterProcessor.processZuulFilter(ZuulFilter) doesn't do anything with the results and just passes it back to runFilters(sType) which we know ignores it.
My next line of questioning was, "well, perhaps you can provide your own FilterProcessor implementation and swap it out and actually use the Object somewhere". But alas, it looks like that isn't the case either unless you want/need to implement a lot more even into the ZuulServlet?
Lastly, I thought, "well, maybe it's just a convention thing". But java.lang.Runnable.run() is void and javax.servlet.Filter.doFilter is also void.
So for now, my best guess is that like all of us at some point in our careers, we sometimes fall into a YAGNI situation; perhaps this is just one example.

Genson Caching of Bean Accessors

I have recently upgraded to Genson 1.3 and I am not 100% sure if this issue is new or not as previously I patched the 0.98 version to make it work.
Context
We are using our own implementation of the BeanMutatorAccessorResolver. This is so that we can dynamically decide whether a property should be serialized or not. Basically we have integrated Genson into our generic jersey REST API interface. Genson does all the serializing and deserializing. When doing a GET requests it is possible for a user to pass fields in the URL in order to filter those he specifically needs (especially for large objects this is necessary where you only need 3 fields or so for displaying a table overview). For example: ?fields=field1, field2, field3. We then know in our implementation of BeanMutatorAccessorResolver exactly which fields to serialize and which ones to ignore. This is mainly intended for speeding up requests and parsing as we are then working with less data.
Problem
Unfortunately it seems that once Genson has read in all the fields via reflection or whatever, it caches that. This would be no problem if we were always requesting the same fields. Unfortunately on some occasions we need more fields then before, but because Genson does not visit our BeanMutatorAccessorResolver a second time it only returns the few fields that it has already cached.
Is there anyway around this? Perhaps there is a better solution than turning cahing off completely - because that would most probably hurt performance, right?
Update
Is seems that I have found the location where this is happening. Basically Genson returns a cached converter in Genson.provideConverter(Type forType) (line: 154).
Converter<T> converter = (Converter<T>) converterCache.get(forType);
At the top of the method I have noticed that it looks for a __GENSON$DO_NOT_CACHE_CONVERTER.
if (Boolean.TRUE.equals(ThreadLocalHolder.get("__GENSON$DO_NOT_CACHE_CONVERTER", Boolean.class))) {
Should I perhaps set this value or is there a better solution?
The problem has been solved thanks to Eugen. The solution can be found here: https://groups.google.com/forum/#!topic/genson/Z1oFHJfA-5w.
Basically you need to extend 3 classes to get this working:
GensonBundle, which you can register with the GensonBuilder.
BaseBeanDescriptorProvider, which gets created in GensonBundle.
BeanDescriptor, which gets created in BaseBeanDescriptorProvider and
which contains the serialize method to adapt to your needs.

Java-Design: Enum state?

I realize (having read other posts on SO as well) that it's bad design (or better said in my case it would also not make sense) to add state to enum constants.
Nevertheless i am finding myself right now in a situation where i need something similar to this.
An application i am writing uses error-constants (enum), which i am using to indicate errors by adding them to a Map<Error, ErrorInfo> (note that these are not application-errors, but "Errors" that are part of the application).
Well - i now realize that i actually also need to indicate an ErrorLevel of INFO, WARN, FATAL for these.
Since the ErrorLevel of an Error depends on the context it occurred in, i cannot statically assign ErrorLevel's to the Error-enums, in other words, an Error.E1 can be of ErrorLevel.WARN one time, but might be ErrorLevel.FATAL another time.
I am thinking about how i could best incorporate this ErrorLevel in my design, but all i have come up with up to now is, to introduce a new class which simply wraps an Error and an ErrorLevel and use it within the Map instead of Error.
Since Errors and their severity seem to me something that must be quite common, i am sure that there are smarter way to do this, so i would greatly appreciate your ideas on how to design this better.
--qu
If I understood your problem correctly, putting a transient state to the enum won't do the trick. As there is only one instance per enum-type by changing the error-level you would not only change it for the current error you are assessing but for all errors of the same type in the application.
You wrote, the errorlevel is depending on the context and at the same time that ErrorInfo describes the context of the occurance of the error. If you can calculate the errorlevel based on the errortype and the context, I would suggest some static method
public static ErrorLevel getLevel(Error, ErrorInfo) {
//..
}
I do not agree in total that it is always bad design adding mutable state to enums. Enums are like Singletons and whenever it makes sense to use a stateful singleton in your application, you can do the same with enum. Like with singletons we just have to keep in mind, that a state change has a pretty global effect.
For sure, stateful enums won't help in your case, because you want context specific error levels.
As an alternative, consider using a simple multimap:
Map<Context, Map<Error, ErrorLevel>> errors;
The idea is to store multiple maps for different contexts. So for a known context (I quickly invented a type...) you get the context specific parameter map.

What is the purpose of `wire()` and `isWired()` in Seam?

I am checking out Seam 2.2.0.GA, and using seam generate-entities it generated Home classes with the methods wire() and isWired(). What are these methods and what purpose do they serve?
isWired() returns a value that indicates whether the object has all its required references to other objects filled (i.e. all required (not null) foreign keys have values). wire() tries to fill these fields with values from the relevant Home objects.
(I hope someone can post a better description.)
The server to "wire" together entity classes together. The later version of Seam have them actually filled out. I've never actually used them in over a year of Seam programming.

JSF - session scoped bean shared by browsers on different machines

We have a search form where the filter is bound to a property on a managed bean (session scope). It's not component binding, its property binding like <h:inputText value="#{searchBean.filter}"/>.
Submitted data from different machines (different sessions, then) is getting mixed. You search "john", and get "mary" just because the guy beside you have just searched "mary". The value of your searchBean.filter is getting his submitted data instead of yours.
I've already googled around a lot and found no solution, just an ocurrence of the same problem.
Have anybody faced this issue already? Any clues?
Thanks!
This can have two causes:
The bean is actually in application scope.
The property in question is declared static.
To fix 1), just ensure that it's in session scope.
To fix 2), just remove the illegal modifier.
Solved! Finally. Thanks guys, for your attention!
It was something like what Balus guessed at the first time. It was a static hidden in a dark corner. I had really double, triple checked everything looking for statics, but -- don't ask me why -- someone created a second bean (Foo) which was holding a static reference for SearchBean.
In the JSP, there was an action="#{foo.search}" instead of searchBean.search. Class Foo had a method with the same name as in SearchBean, that was doing no more than a searchBean.search();.
I think pressure for fixing this bug for yesterday didn't allow me to see this trap in the JSP.

Categories

Resources