Jackson Included.NON_DEFAULT not working in 2.7.0 - jackson

I'm trying to upgrade from Jackson 2.3 to Jackson 2.7 , and it appears the #JsonIgnore(Include.NON_DEFAULT) behavior has changed.
With the following code
package jackson;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public static void main (String args[]) throws Exception {
MyClass foo = new MyClass();
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(foo));
}
public static enum MyEnum { A, B, C };
public static class MyClass {
public String name = "John";
#JsonInclude(Include.NON_DEFAULT)
public MyEnum myEnum = MyEnum.A;
}
}
I get this output using 2.7:
{"name":"John","myEnum":"A"}
and the following using 2.3:
{"name":"John"}
How do I replicate the behavior in 2.3 using version 2.7 ?

According to the bug ticket I put in for this, it is working as intended and that functionality can be achieved by structuring your class as:
#JsonInclude(JsonInclude.Include.NON_DEFAULT)
public static class MyClass {
#JsonInclude(JsonInclude.Include.ALWAYS)
public String name = "John";
public MyEnum myEnum = MyEnum.A;
}
See the ticket for a more thorough explanation from the author.

Related

Class order scanning bug in Neo4J OGM

I am having issues with the order classes are scanned in Neo4 OGM.
Take the following minimal Spring Data Rest + Spring Boot application:
#NodeEntity("Country")
public class Country extends CountryRevision {
}
#NodeEntity("CountryRevision")
public class CountryRevision extends RevisionEntity<CountryRevision> {
String name;
}
public abstract class RevisionEntity<T> {
#Id #GeneratedValue(strategy = UuidStrategy.class)
String id;
#Relationship
T previousRevision;
}
#RepositoryRestResource(collectionResourceRel = "countries", path = "countries")
public interface CountryRepository extends Neo4jRepository<Country, String> {}
#RepositoryRestResource(collectionResourceRel = "countryRevisions", path = "country-rev")
public interface CountryRevisionRepository extends Neo4jRepository<CountryRevision, String> {}
#SpringBootApplication
#EnableNeo4jRepositories(basePackageClasses = DemoApplication.class)
#EntityScan(basePackageClasses = DemoApplication.class)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
When POSTING to /country-rev, I get the following error:
java.lang.RuntimeException: Field previousRevision not found in class com.example.demo.CountryRevision or any of its superclasses
at org.neo4j.ogm.metadata.ClassInfo.getField(ClassInfo.java:601) ~[neo4j-ogm-core-3.2.1.jar:3.2.1]
at org.neo4j.ogm.metadata.FieldInfo.readProperty(FieldInfo.java:411) ~[neo4j-ogm-core-3.2.1.jar:3.2.1]
What is really strange is that if I modify the "Country" class name to something else, like "Toto", everything works fine.
I debugged the way the OGM is initialized. It looks like depending on the classname, the map containing all OGM ClassInfos will be processed in a different order (in DomainInfo.prepareClass()), which will produce different results.
My question is: is there anything wrong with the previous example, or is this a bug in the OGM?
It's definitely an OGM issue which I reported here:
https://github.com/neo4j/neo4j-ogm/issues/704

java.lang.NullPointerException: null on AutoWiring a bean in StandAlone App

When trying to use #AutoWire feature with one of StandAlone Application unable to do so instead getting Null Pointer Exception. Please highlight my mistakes if any. Your help is appreciated.
Spring Ver 5.1.5.RELEASE and we're not using any xml config file to tell spring there are annotated classes to look into instead using #ComponentScan or #EnableAutoConfiguration at the top of AppConfig and boost strap the Context from main() class as a first line. But Autowiring works perfectly with internal bean/java classes of jdk(Environment) but not with custom POJO classes. If we're trying to get through getBean method then it works. But I'm trying to avoid creating context everywhere and using getBean() Please Refer below and help me only with your valuable guidelines.
public class ContextMaster {
private static AnnotationConfigApplicationContext appContext;
public static AnnotationConfigApplicationContext getApplicationContext() {
if (appContext == null) {
appContext = new AnnotationConfigApplicationContext(ContextConfig.class);
//appContext = new AnnotationConfigApplicationContext("com.xx.xx.xxx","xx.xxx.xxxx.xxx.datamanager");
logger.debug("Context Invoked !!");
}
return appContext;
}
}
#Configuration
#EnableAutoConfiguration
#PropertySource("classpath:db.properties")
#EnableTransactionManagement
#ComponentScans(value = {
#ComponentScan(basePackages = "xxxxx.datamanager"),
#ComponentScan(basePackages = "com.xx.xx.xxx"),
#ComponentScan(basePackages = "com.xx.xx.xxx.utils")})
public class AppConfig {
#Autowired
private Environment env;
#Bean
public DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
//LocalSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();
factoryBean.setDataSource(getDataSource());
Properties props=new Properties();
props.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
props.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
props.put("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class"));
factoryBean.setHibernateProperties(props);
factoryBean.setAnnotatedClasses(xx.class, xxxx.class, xxxx.class, xxx.class);
return factoryBean;
}
#Bean
public HibernateTransactionManager getTransactionManager() {
return transactionManager;
}
}
// Here is NPE thrown when tried with auto-configured bean
#Component
public class Good extends Good11 {
#Autowired
private RxxxDyyyyHelper rdh;
//RxxxDyyyyHelper rdh =
ContextHelper.getApplicationContext().getBean(RxxxDyyyyHelper .class);
rdh.setProperty(); // NPE here
rdh.getProperty(); // NPE
}
// Here we're trying to initiate the LosUtils class
public class LosUtils {
public static void main(String args[]) throws Exception {
AnnotationConfigApplicationContext applicationContext = `ContextHelper.getApplicationContext();`
}
It seems like you didn't put the full code here, because your Good class won't compile this way..

How to access the public variable in plugin1 from plugin2 using OSGI framework

I'm new to OSGI framework and I'm trying to access the 'Derived' Class variable 'publicVariable' from another class 'Derived2' like "Derived.publicVariable" but publicVariable is always shows null. I really appreciate if someone can help me out with this.
Thanks
Manifest file - Derived2
Require-Bundle:com.xxxxxx.Derived1
Java code
abstract class Base {
protected Vector <String> supportedCommands = new Vector <String> ();
protected abstract void initialiseCommands();
}
class Derived extends Base {
private static Derived derivedPlugin = null;
public Derived()
{
derivedPlugin = this;
}
public static Derived getPlugin()
{
return derivedPlugin;
}
public String publicVariable = null;
protected void initialiseCommands()
{
publicVariable = "someData";
System.out.println("Derived" + publicVariable);
}
}
class Derived2 extends Base {
protected void initialiseCommands()
{
supportedCommands.add(Derived.getPlugin().publicVariable);
System.out.println("IMRSAUtilitiesPlugin" +supportedCommands);
}
Also referred below link, which is a similar issue but i'm not using any static variable, it is just a public variable.
how use Singleton object in different class loader....?
The code in the question will not compile. You are trying to access an instance field (publicVariable in class Derived) in a static way, i.e. Derived.publicVariable.
OSGi does not change the semantics of the Java language, and if you cannot even compile your code then OSGi will certainly not be able to run it.

Protobuf-net / NetCore2: Deserialization ignores annotated private fields

Edit: The problem was with Nancy. Protobuf-net (de)serializes marked private fields just fine.
I am running a NetCore 2.0 unit test project. Protobuf-net appears to be ignored private fields even though the have the [ProtoMember] attribute.
[ProtoContract]
internal class Model
{
[ProtoMember(1)]
public int Example { get; private set; } // Works
[ProtoMember(2)]
private List<int> _a; // Not deserialized unless made public
public IEnumerable<int> A => this._a;
public Model(int example, IEnumerable<int> a)
{
this.Example = example;
this._a = a.ToList(); // Copy prevents mutation
}
private Model() // For deserialization
{
}
}
I have used a public IEnumerable<int> to avoid mutability and hide implementation details. It is backed by a private List<int> to allow serialization. However, protobuf-net will only deserialize the field if I make it public. The serialization, on the other hand, will actually include the data even if the field is private.
Is this intended behavior? Is there are a clean way to make protobuf-net honor the marked private field when deserializing?
P.S. The same behavior is seen for non-collection members, but I have demonstrated with IEnumerable/List because it shows the reason for this approach.
The following works identically (apart from the first line of the output) when targetting netcoreapp2.0 or net45. I'd be happy to help, but I'd need to see an example that fails. I'm using:
<PackageReference Include="protobuf-net" Version="2.3.6" />
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using ProtoBuf;
[ProtoContract]
internal class Model
{
[ProtoMember(1)]
public int Example { get; private set; } // Works
[ProtoMember(2)]
private List<int> _a; // Not deserialized unless made public
public IEnumerable<int> A => this._a;
public Model(int example, IEnumerable<int> a)
{
this.Example = example;
this._a = a.ToList(); // Copy prevents mutation
}
private Model() // For deserialization
{
}
}
static class Program
{
static void Main()
{
#if NETCOREAPP2_0
Console.WriteLine(".NET Core 2.0");
#elif NET45
Console.WriteLine(".NET 4.5");
#endif
var obj = new Model(123, new int[] { 4, 5, 6 });
var clone = Serializer.DeepClone(obj);
Console.WriteLine(clone.Example);
foreach (var val in clone.A)
{
Console.WriteLine(val);
}
}
}

How to define string name as class in java

I am using Jackson parser for JSON parsing in android app. The JSON data is in following form
data: {
train_number: "12951",
chart_prepared: false,
class: "2A"
}
How to parse property with class name in Java?
Please, help me.
At the beginning - your JSON is not valid. It should look like this:
{"train_number":1,"chart_prepared":false,"class":"2A"}
You can change default name property using #JsonProperty annotation.
Your POJO class should looks like that:
class Data {
private int train_number;
private boolean chart_prepared;
#JsonProperty(value = "class")
private String clazz;
...
}
Now you can build simple test method:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonProgram {
public static void main(String[] args) throws Exception {
Data data = new Data();
data.setTrain_number(1);
data.setClazz("2A");
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(data);
System.out.println(json);
System.out.println(objectMapper.readValue(json, Data.class));
}
}
Above program prints:
{"train_number":1,"chart_prepared":false,"class":"2A"}
Data [train_number=1, chart_prepared=false, clazz=2A]