Tag Archives: Maven

[Solved]: JAXB empty Tag without xsi:nil=”true” for null values by using jaxb.properties


Generally when we do marshaling from JAVA object to XML through JAXB, the null values String or other objects not considered while marshalling and xml tag for these objects not generated.

If we need to get xml tags also for null values object then define these property in model class with attribute nillable=true.

 @XmlElement(name = "description", nillable = true)
 private String description;

After adding nillable=true property attribute this will generate output XML tag as below

<description xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

Problem Statement

Here problem is we don’t want the XML description tag with schema url and xsi:nil=”true” as above. We want only the empty tag for XML as below

<description />

Solutions

Here the problem is when any value in model class property is found as null the JAXB does not call any xmlAdaptor and generate tag with schema link with xsi:nil=”true”.

To solve this problem we can use third party JAXB provider EclipseLink JAXB (MOXy) . It’s required to make below changes on your application and model class.

  • Add this EclipseLink MOXy dependency in you application
<dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.moxy</artifactId>
        <version>2.6.8</version>
    </dependency>
  • Add XmlNullPolicy on all the fields of model where need to generate empty tag for null values.
 @XmlElement(name = "description", nillable = true)
 @XmlNullPolicy(emptyNodeRepresentsNull = true, nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE)
 private String description;
  • Now we need to set below property in our JVM while marshaling through java object to XML.
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

There are following ways to add above property based on you application need.

Solution 1: In case of simple java application, you can add this line of code before marshaling

System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");

Solution 2: Create jaxb.properties file in your each model package/resource folder and add below property

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Note: Once you will run your code in your local machine it will generate empty tag but you will face problem when deploy application after making maven build because this property file will not add in your generated classes folder model packages. In this case you have to add below lines of code in pom.xml to copy jaxb.properties file in model package.

<plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <executions>
                <execution>
                    <id>copy-resources01</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${basedir}/target/classes/model package location</outputDirectory>
                        <encoding>UTF-8</encoding>
                        <resources>
                            <resource>
                                <directory>${basedir}/src/main/resources</directory>
                                <includes>
                                    <include>jaxb.properties</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Solution 3: If your application is Spring boot then you can also pass the below arguments while deploying application.

-Djavax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

or

Add the property in application.properties/application.yml file

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

This solution will also help when you are having multiple packages for model classes and no need to include jaxb.properties in each package.

Conclusion

In this topic you learn about the steps to generate empty tags for XML incase null values for Java objects. you can also learn about the copy of jaxb.properties file in packages by maven. Incase of having multiple packages for model classes you can follow solutions to handle it.

Let me know about your thoughts on these solutions.

Happy Learning !!!

[Solved] java.nio.file.NoSuchFileException: XYZ


NoSuchFileException occurred when trying to attempt access a file or directory which is not exist in given location.

NoSuchFileException is sub class of FileSystemException. This exception  introduced in Java 7.

Example for NoSuchFileException

This example is throwing NoSuchFileException because trying to access a file student_data.json which is not exist on default location.

package com.fiot.json.jackson;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fiot.json.jackson.pojo.Student;

public class ConvertJsonToArrayList {

	public static void main(String[] args) {
		try
		{
		byte[] mapData = Files.readAllBytes(Paths.get("student_data.json"));
		Student[] studentArr = null;

		ObjectMapper objectMapper = new ObjectMapper();
		studentArr = objectMapper.readValue(mapData, Student[].class);
		List studentList=Arrays.asList(studentArr);
		System.out.println("Student 1 \n"+studentList.get(0));
		System.out.println("Student 2 \n"+studentList.get(1));

		}
		catch(JsonMappingException ex)
		{
			ex.printStackTrace();
		}
		catch(IOException ex)
		{
			ex.printStackTrace();
		}

	}

}

Exception Stacktrace


java.nio.file.NoSuchFileException: student_data.json
    at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(Unknown Source)
    at java.nio.file.Files.newByteChannel(Unknown Source)
    at java.nio.file.Files.newByteChannel(Unknown Source)
    at java.nio.file.Files.readAllBytes(Unknown Source)
    at com.fiot.json.jackson.ConvertJsonToArrayList.main(ConvertJsonToArrayList.java:18)

Solutions

There are couple of solutions to handle such situations:

  1. Use fully qualified file path such as “C:/data/student_data.json” but that will help only when your program is going to run on local machine. While working with enterprise application always use relative paths.
  2. If your file in source directory use path as “src/student_data.json”
  3. If your project is maven project, always write script to copy file which you want to access or keep in resource folder to access because maven project create different directory structure after build.

Solution depend on your project requirement. You can use below code to get qualified full path of a file

public static void main(String [] args) {

    String filename="student_data.json";
    //To get path of file
    Path path = Paths.get(filename);
    //To print absolute path of file
    System.out.println(path.getAbsolutePath());

You would like to see

Follow below link to see more Java issues solutions

[Solved] Could not transfer artifact org.springframework:XYZ from/to central (https://repo.maven.apache.org/maven2)


Generally this error message shows in pom.xml when create new project with dependencies or add new dependencies in pom.xml.

Reason to cause this error

There are several reason to cause this error as below because maven is unable to connect to Maven repository at http://repo1.maven.org/maven2.

  1. Proxy
  2. Network issue
  3. .lastUpdate file for dependency

Could not transfer artifact org.springframework:spring-expression:jar:5.1.6.RELEASE from/to central (https://repo.maven.apache.org/maven2): C:\Users\saurabh.gupta1\.m2\repository\org
 \springframework\spring-expression\5.1.6.RELEASE\aether-fa07bf3e-4fa1-4911-bcad-3319e4b2480e-spring-expression-5.1.6.RELEASE.jar-in-progress (The system cannot find the file 
 specified) org.eclipse.aether.transfer.ArtifactTransferException:
 

Solutions

There are few ways i find out to resolve this issue:

Maven Force Update of Snapshot/Releases

Follow below steps to to resolve this issue and clear all dependencies error in eclipse.

  1. Right click on project.
  2. Go to Maven
  3. Update project , the check the above option “Force update of Snapshot/Releases“.
  4. Click on Ok.
  5. If not fixed restart your eclipse.

Maven Force Update 1

Maven Force Update 2

Maven access through Proxy

Update your proxy configuration in maven settings.xml file and put it inside .m2 folder

C:\Users\USER NAME.m2

proxy settings





 
    
      myproxy
      true
      http
      user name  
      password   
      127.56.8.64        
      80                 
      local.net|some.host.com 
      
  

You don’t need to touch , and sections, unless you really know what are these tags.

After updating this setting restart eclipse and follow the steps in Maven Force update of Snapshot/Releases.

Remove .lastUpdated file

If this problem is not resolved yet got to .m2/repository/ to dependency sub directory and remove .lastUpdate file inside of it or delete complete directory for this particular dependency and again follow the steps in Maven Force update of Snapshot/Releases.

For Example as for above issue directory location showing in exception as

C:\Users\saurabh.gupta1.m2\repository\org
\springframework\spring-expression\5.1.6.RELEASE

Above solutions are my research to resolve this issue if you find out or know other ways please suggest in comments.

Elasticsearch REST JAVA API


Elasticsearch 5 provides low-level client API’s to communicate with Elasticsearch Cluster over HTTP by JAVA. Because of REST services and JSON able to communicate with all version of Elasticseach and across firewall also.

Elasticsearch REST Client sent http requests internally by using Apache Http Async Client.

In case of version change on Elasticsearch Cluster no need to change for client and will not impact any communication.

Initial Release Version : 5.0.0-alpha4

Elasticsearch REST Features

  • Keep the connection persistent.
  • Logged request and response by Elasticsearch Rest API.
  • Load balancing across all available nodes.
  • Failover in case of node fails and upon specific response codes.
  • Provide sniffing to the discovery of clusters node.
  • Minimum Dependencies.

Pre-Requisite

Elasticsearch Rest required minimum Java version is 1.7

Elasticsearch REST Java API Configuration

 Maven Configuration

Add below dependency in pom.xml file to import all library.

.
      org.elasticsearch.client
      rest
      5.1.2

Gradle Configuration

Add below dependency in build.gradle file to import all library.

dependencies {   compile 'org.elasticsearch.client:rest:5.1.2'}

Read More on Elasticsearch REST

Integration

Integrate Filebeat, Kafka, Logstash, Elasticsearch and Kibana