Kooin-Shin
Posted on January 4, 2021
Intro.
Some far ago, I've been introducing 'How to manage your configuration file with YAML in Java programmatically' in previous post.
if you wanna know it, follow link: How to manage your configuration file with YAML in Java programmatically
It was about handing Yaml file contents to create Java Bean object. That was including information of a configuration or serialized Valued-Object(VO). Simply to say, It was about load or dump information between Yaml file and Java object.
Meanwhile, Someone who has keen thinking asked how to access a Yaml file in internal resources?
So I realized it's need,
Here I would show how to load and dump Yaml file in Jar.
Setting up environments.
- As same as previous post, To handle Yaml file, We need SnakeYAML library.
- For our works, Any IDE Tools is able to use, But I gonna to use Visual Studio Code(VSCODE) on fever in these days.
- And we have to set SnakeYAML MAVEN dependency to POM.xml. In previous post I used Gradle but now, Would use MAVEN for diversity :)
- If you are prepared with above things, Readied to start coding.
Designing Java Class.
Before we gonna see implemented code, I would show you entire design of our works.
- We will define java class named "YamlInternalHandler" to handle Yaml file in Jar.
- Will define two method named "loadInternalJar" and "dumpInternalJar". First one is to load Yaml's contents to Java object with jar entry path and a Class object to be loaded the contents. Second one is to dump a object values to Yaml file in Jar with jar entry path and instance of Java object including a values.
- We could load and dump a specified object mapping with a Yaml file in jar. Surely, It's good to make sure syntax of Yaml file in Jar.
Let's dive into code.
Contents of Yaml file in Jar is down below.
firstName: Kooin
lastName: Shin
age: 48
profile:
- character: bright
hobby: claiming
address: Seoul
postalCode: 123
- character: delight
hobby: ski
address: Seoul
postalCode: 123
Java Bean to be loaded contents is 'Customer' and 'Profile' representing Yaml's values.
package org.chaostocosmos.doc.yml;
import java.util.List;
public class Customer {
private String firstName;
private String lastName;
private int age;
private List<Profile> profile;
public Customer() {}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public List<Profile> getProfile() {
return this.profile;
}
public void setProfile(List<Profile> profile) {
this.profile = profile;
}
@Override
public String toString() {
return "{" +
" firstName='" + firstName + "'" +
", lastName='" + lastName + "'" +
", age='" + age + "'" +
", profile='" + profile + "'" +
"}";
}
}
package org.chaostocosmos.doc.yml;
public class Profile {
String character;
String hobby;
String address;
int postalCode;
public Profile() {}
public String getCharacter() {
return this.character;
}
public void setCharacter(String character) {
this.character = character;
}
public String getHobby() {
return this.hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public int getPostalCode() {
return this.postalCode;
}
public void setPostalCode(int postalCode) {
this.postalCode = postalCode;
}
@Override
public String toString() {
return "{" +
" character='" + character + "'" +
", hobby='" + hobby + "'" +
", address='" + address + "'" +
", postalCode='" + postalCode + "'" +
"}";
}
}
And Now we gonna show core code of 'YamlInternalHandler' class.
package org.chaostocosmos.doc.yml;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.constructor.Constructor;
/**
* Yaml Internal Handler
*
* @author Kooin-Shin
* @since 2021.01.04
*/
public class YamlInternalHandler {
/**
* Jar file having yaml file
*/
File file;
/**
* Constructor
* @param file
* @throws IOException
*/
public YamlInternalHandler(File file) throws IOException {
this.file = file;
}
/**
* Load object from internal yaml file in jar
* @param jarEntry
* @param clazz
* @return
* @throws IOException
*/
public Object loadInternalJar(String jarEntry, Class<? extends Object> clazz) throws IOException {
if (!jarEntry.endsWith(".yml")) {
throw new IllegalArgumentException("This component only support a yaml file in jar!!!");
}
JarFile jarFile = new JarFile(this.file); //Create JarFile object
JarEntry entry = jarFile.getJarEntry(jarEntry); //Get JarEntry specified by first parameter
InputStream is = jarFile.getInputStream(entry); //Get InputStream from JarFile by JarEntry
Constructor constructor = new Constructor(clazz); //Create Constructor object specified by second parameter
Yaml yaml = new Yaml(constructor); //Create Yaml object with Constructor object
Object obj = yaml.load(is); //Load contents to object instance
is.close(); //Close InputStream
jarFile.close(); //Close JarFile
return obj;
}
/**
* Dump object to yaml file in jar
* @param jarEntry
* @param obj
* @throws FileNotFoundException
* @throws IOException
*/
public void dumpInternalJar(String jarEntry, Object obj) throws FileNotFoundException, IOException {
JarOutputStream jos = new JarOutputStream(new FileOutputStream(this.file)); //Create JarOutputStream object
jos.putNextEntry(new ZipEntry(jarEntry)); //Put jar entry by first parameter
DumperOptions options = new DumperOptions(); //Set dump options
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options); //Create Yaml object with DumperOptions object
yaml.dump(obj, new OutputStreamWriter(jos)); //Dump contents of second parameter
jos.close(); // Close JarOutputStream
}
public static void main(String[] args) throws IOException {
File file = new File("D:\\Projects\\chaos-commons\\yaml.jar");
YamlInternalHandler ymlHandler = new YamlInternalHandler(file);
Customer customer = (Customer) ymlHandler.loadInternalJar("tmp/yaml/Customer.yml", Customer.class);
System.out.println(customer.toString());
customer.setFirstName("Jim ");
customer.getProfile().get(0).setAddress("Busan");
ymlHandler.dumpInternalJar("tmp/yaml/Customer.yml", customer);
}
}
Conclusion
Above code is assumed very simple cases of accessing of a Yaml in Jar. As a situation, It can be transformed, modified and improved.
Always elastic thinking is yours!!!
Good Luck!!!
Posted on January 4, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.