Is there a way that i can unregister a module from Jackson ObjectMapper? - json

I'm registering KeyDeseriliser to ObjectMapper. After reading JSON I want to unregister this module. Because my ObjectMapper is static and I don't want to use this module in any other places.
SimpleModule module = new SimpleModule("EnhancedDatesModule", new Version(0, 1, 0, "test", "Test-id",
"testest"));
module.addKeyDeserializer(EncounterCURN.class, new MapKeyDeseriliser());
objectMapper.registerModule(module);
Map<EncounterCURN, Collection<EncounterTodo>> encounterTodosByEncounter = mapReader.readValue(nodes.get("todos"));

No, you can not do this. You should create another ObjectMapper and use it.
By the way, static fields this is a not a good habit of programming in Java. You should avoid situations like this where such kind of objects are static.

The module has a setSerializers, according to the docs:
/**
* Resets all currently configured serializers.
*/
public void setSerializers(SimpleSerializers s) {
_serializers = s;
}
So, what you can do is call the setter with a new empty SimpleSerializers object.
Disclaimer: I am not 100% sure how this will workout in from a thread-safety point of view.

Related

Unable to mock the local variable inside a method in java [duplicate]

I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class Animal {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());

How to mock when i create object like the following

How to mock listAPiMetrics when my code looks like this
List<JSONObject> metrics = new ApiMetricsClient().listApiMetrics(new ApiIdList(apiIds));
You can not mock that behavior. Because you are initiate your object inside code. You need to inject dependencies via contrutor or somehow. Basically, you need to do dependency injection.
Some mock frameworks (like moq from c#) able to mock only interface or abstract types so you need to inject your dependencies as interface which this is the most common way in general. Some frameworks like mockito/powermock allow to mock concrete types too (powermock also can be able to mock private methods as I remember).
Change your code to work as below :
class YourClass {
private IApiMetricsClient apiMetricClient;
public YourClass(IApiMetricsClient apiMetricClient) {
this.apiMetricClient = apiMetricClient;
}
public [returnType] yourMethod() {
List<JSONObject> metrics = this.apiMetricClient.listApiMetrics(new ApiIdList(apiIds));
// other logics and return data or whatever
}
}

Change the JsonConverter date format for Play 2.5

I've tried to configure the ObjectMapper for the built-in play.libs.Json. I've followed the documentation, however the MapperLoader seems to be ignored.
This is what I do (based on the documentation):
Create CustomMapperLoader
public class JsonMapperLoader extends GuiceApplicationLoader {
#Override
public GuiceApplicationBuilder builder(final Context context) {
ObjectMapper mapper = Json.newDefaultMapper()
.setDateFormat(new SimpleDateFormat(Constants.ISO8601_DATE_FORMAT));
Json.setObjectMapper(mapper);
return super.builder(context);
}
}
Explicitly load the loader in application.conf:
play.application.loader = "JsonMapperLoader"
When I serialize date, it still gives me the time-stamp instead of specified format.
I have several workarounds for this:
I set the object mapper during the creation of
ApplicationController
I disable the play.core.ObjectMapperProvider and enable my CustomObjectMapperProvider.
Is there any better alternatives for this issue?
Thanks & Regards,
I never tried the method suggested in the manual (with custom ApplicationLoader). I use another technique. In short: there is a class, which configures the ObjectMapper; the class is injected it in the Module as a singleton.
You can see the full code example here.

How to customize Jackson type information mechanism

In Jackson, I am using annotation #JsonTypeInfo to include polymorphism support.
If, I do not want to go with annotation based approach, I can use global default typing or override the type information handling module.
I have tried global type information but it is emitting type information for all non final type.
What I need ,
I want to include type information only for polymorphic type.
I want to change default format of type info (to key-value pair)
Is it possible to achieve above two points just by twitting global configuration?
If not, what extension point should I used used to customize type-information module ?
I have read JacksonAnnotationIntrospector is the class which deals with type info.
Should I customize it to achieve above mentioned two points?
Help with Example will be well and good.
You can use Jackson's DefaultTypeResolverBuilder for this purpose. Extend this class and override the useForType method appropriately. Here is an example that adds type information only for the classes belonging to the test.jackson package (and sub-packages):
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTypeResolverBuilder;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
public class CustomTypeResolverBuilder extends DefaultTypeResolverBuilder
{
public CustomTypeResolverBuilder()
{
super(DefaultTyping.NON_FINAL);
}
#Override
public boolean useForType(JavaType t)
{
if (t.getRawClass().getName().startsWith("test.jackson")) {
return true;
}
return false;
}
}
Now, consider that you have Foo.java in test.jackson package and Bar.java in org.myorg package, each containing an int variable called "integer" and a String variable called "string".
You can serialize objects of these two classes this way:
ObjectMapper objectMapper = new ObjectMapper();
TypeResolverBuilder<?> typeResolver = new CustomTypeResolverBuilder();
typeResolver.init(JsonTypeInfo.Id.CLASS, null);
typeResolver.inclusion(JsonTypeInfo.As.PROPERTY);
typeResolver.typeProperty("#CLASS");
objectMapper.setDefaultTyping(typeResolver);
Foo foo = new Foo(10, "Foo");
Bar bar = new Bar(20, "Bar");
System.out.println(objectMapper.writeValueAsString(foo));
System.out.println(objectMapper.writeValueAsString(bar));
The corresponding output will be:
{"#CLASS":"test.jackson.Foo","integer":10,"string":"Foo"}
{"integer":20,"string":"Bar"}
You can also customize the name of the attribute that represents the type ("#CLASS" in the above example). Hope this helps!
You can use the Moonwlker library.
With it, you can create an ObjectMapper like this:
ObjectMapper objectMapper = new ObjectMapper();
MoonwlkerModule module =
MoonwlkerModule.builder()
.fromProperty("#CLASS").toSubclassesOf(Animal.class)
.build();
objectMapper.registerModule(module);
And then use that mapper to (de)serialize. The Moonwlker website contains more details and configuration options.

Json <-> Java serialization that works with GWT [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am looking for a simple Json (de)serializer for Java that might work with GWT. I have googled a bit and found some solutions that either require annotate every member or define useless interfaces. Quite a boring. Why don't we have something really simple like
class MyBean {
...
}
new GoodSerializer().makeString(new MyBean());
new GoodSerializer().makeObject("{ ... }", MyBean.class)
Take a look at GWT's Overlay Types. I think this is by far the easiest way to work with JSON in GWT. Here's a modified code example from the linked article:
public class Customer extends JavaScriptObject {
public final native String getFirstName() /*-{
return this.first_name;
}-*/;
public final native void setFirstName(String value) /*-{
this.first_name = value;
}-*/;
public final native String getLastName() /*-{
return this.last_name;
}-*/;
public final native void setLastName(String value) /*-{
this.last_name = value;
}-*/;
}
Once you have the overlay type defined, it's easy to create a JavaScript object from JSON and access its properties in Java:
public static final native Customer buildCustomer(String json) /*-{
return eval('(' + json + ')');
}-*/;
If you want the JSON representation of the object again, you can wrap the overlay type in a JSONObject:
Customer customer = buildCustomer("{'Bart', 'Simpson'}");
customer.setFirstName("Lisa");
// Displays {"first_name":"Lisa","last_name":"Simpson"}
Window.alert(new JSONObject(customer).toString());
Another thing to try is the new AutoBean framework introduced with GWT 2.1.
You define interfaces for your beans and a factory that vends them, and GWT generates implementations for you.
interface MyBean {
String getFoo();
void setFoo(String foo);
}
interface MyBiggerBean {
List<MyBean> getBeans();
void setBeans(List<MyBean> beans>;
}
interface Beanery extends AutoBeanFactory{
AutoBean<MyBean> makeBean();
AutoBean<MyBiggerBean> makeBigBean();
}
Beanery beanFactory = GWT.create(Beanery.class);
void go() {
MyBean bean = beanFactory.makeBean().as();
bean.setFoo("Hello, beans");
}
The AutoBeanCodex can be used to serialize them to and from json.
AutoBean<MyBean> autoBean = AutoBeanUtils.getAutoBean(bean);
String asJson = AutoBeanCodex.encode(autoBean).getPayload();
AutoBean<MyBean> autoBeanCloneAB =
AutoBeanCodex.decode(beanFactory, MyBean.class, asJson );
MyBean autoBeanClone = autoBeanCloneAB.as();
assertTrue(AutoBeanUtils.deepEquals(autoBean, autoBeanClone));
They work on the server side too — use AutoBeanFactoryMagic.create(Beanery.class) instead of GWT.create(Beanery.class).
The simplest way would be to use GWT's built-in JSON API. Here's the documentation. And here is a great tutorial on how to use it.
It's as simple as this:
String json = //json string
JSONValue value = JSONParser.parse(json);
The JSONValue API is pretty cool. It lets you chain validations as you extract values from the JSON object so that exceptions will be thrown if anything's amiss with the format.
It seems that I found the right answer to my question
I figured out that bean to json and json to bean conversion in GWT isn't a trivial task. Known libraries would not work because GWT would require their full source code and this source code must use only Java classes that are amoung emulated by GWT. Also, you cannot use reflection in GWT. Very tough requirements!
I found the only existing solution named gwt-jsonizer. It uses a custom Generator class and requires a satellite interface for each "jsonable" bean. Unfortunately, it does not work without patching on the latest version of GWT and has not been updated for a long time.
So, I personally decided that it is cheaper and faster to make my beans khow how to convert themselves to and from json. Like this:
public class SmartBean {
private String name;
public String getName() { return name; }
public void setName(String value) { name = value; }
public JSONObject toJson() {
JSONObject result = new JSONObject();
result.put("name", new JSONString(this.name));
return result;
}
public void fromJson(JSONObject value) {
this.name = value.get("name").isString().stringValue();
}
}
JSONxxxx are GWT built-in classes that provide low-level json support.
RestyGWT is a powerful library for encoding or decoding Java Object to JSON in GWT:
import javax.ws.rs.POST;
...
public interface PizzaOrderCodec extends JsonEncoderDecoder<PizzaOrder> {
}
Then:
// GWT will implement the interface for you
PizzaOrderCodec codec = GWT.create(PizzaOrderCodec.class);
// Encoding an object to json
PizzaOrder order = ...
JSONValue json = codec.encode(order);
// decoding an object to from json
PizzaOrder other = codec.decode(json);
It has also got several easy to use API for consuming Restful web services.
Have a nice time.
Check this:
GWT Professional JSON Serializer:
http://code.google.com/p/gwtprojsonserializer/
!Works with GWT 2.0+!
json.org/java seems to be included with GWT these days:
gwt-servlet-deps.jar\org\json\
Or, this project seems to be comprehensive:
http://code.google.com/p/piriti/
In Google Web Toolkit Applications, pages 510 to 522, the author, Ryan Dewsbury, shows how to use GWT code generation to do serialization to and from XML and JSON documents.
You can download the code here; you want the chapter 10 code bundles, and then you want to look in the src/com/gwtapps/serialization package. I did not see a license for this code, but have emailed the author to see what he says. I'll update this if he replies.
Issues with this solution:
You have to add a marker interface on all your objects that you want serialized (he uses java.io.Serializable but I imagine you could use others--if you are using hibernate for your backend, your pojos might already be tagged like this).
The code only supports string properties; it could be extended.
The code is only written for 1.4 and 1.5.
So, this is not an out of the box solution, but a great starting point for someone to build a JSON serializer that fits with GWT. Combine that with a JSON serializer on the server side, like json-lib and you're good to go.
I also found this project (again, some marker interface is required).
Try this serializer from Google Code: http://code.google.com/p/json-io/
If you need to write or read JSON format in Java, this is the tool to use. No need to create extra classes, etc. Convert a Java object graph to JSON format in one call. Do the opposite - create a JSON String or Stream to Java objects. This is the fastest library I have seen yet to do this. It is faster than ObjectOutputStream and ObjectInputStream in most cases, which use binary format.
Very handy utility.
You may want to checkout this project https://gerrit.googlesource.com/gwtjsonrpc/
It's a library created in order to support a code review system for Android, Gerrit, but it's a stand-alone module meant to be embedded into any GWT project, not just Gerrit.
A reasonable tutorial is probably the README in the top level of the directory. It's quite similar to standard GWT RPC but it uses JSON encoding. It also has built-in XSRF protection.
I seem to be answering this question a lot...
There's a page on code.google.com titled Using GWT for JSON Mashups. It's (unfortunately) way over my head, as I'm not that familiar with GWT, so it may not be helpful.
OK, I deleted my previous answer because it turned out to be exactly what you didn't want.
I don't know how well it works with GWT, but we use the json-lib library to serialize objects in a normal Java project where I work.
It can create a JSONObject directly from a JavaBean, then use the resulting JSONObject's toString() method to get the actual JSON string back.
Likewise, it can also turn JSON back into a JavaBean.
Not sure if Jackson would work for you.
I don't know if there's GWT-specific you are looking for; if not it should work.
But its serialization/deserialization works quite well, like:
// read json, create object
ObjectMapper mapper = new ObjectMapper();
MyBean bean = mapper.readValue(jsonAsString, MyBean.class);
// and write out
StringWriter sw = new StringWriter();
mapper.writeValue(sw, user);
String jsonOut = sw.toString();
You do need accessors (getX() to serialize, setX() to deserialize; can annotate methods with other names), but that's about it.