Method should never be called while writing java object as YAML file - spring-boot

I am trying to write java object as an YAML file. And getting the below exception. Any pointer to fix this?
Code
public void writeRequestRoot(RequestRoot requestRoot, String fileName) {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
try {
mapper.writeValue(new File("fileName), requestRoot);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
Logs
Method should never get called
java.lang.IllegalStateException: Method should never get called
at com.fasterxml.jackson.dataformat.yaml.YAMLFactory._createUTF8Generator(YAMLFactory.java:575)
at com.fasterxml.jackson.dataformat.yaml.YAMLFactory._createUTF8Generator(YAMLFactory.java:15)
at com.fasterxml.jackson.core.JsonFactory.createGenerator(JsonFactory.java:1228)
at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:3351)
at com.scb.nexus.beats.helper.YamlReaderWriter.writeRequestRoot(YamlReaderWriter.java:45)
Dependency
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.1.2"

Dependency issue with the below dependency it works
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.12.3"

Related

How to configure the ObjectMapper for Unirest in a spring boot project

I am using Unirest in a project which is working fine for me. However, I want to post some data and do not want to escape all the JSON as it looks ugly and is just a pain in the neck.
I found a few links on how to configure the ObjectMapper for Unirest and it gives this code.
Unirest.setObjectMapper(new ObjectMapper() {
com.fasterxml.jackson.databind.ObjectMapper mapper =
new com.fasterxml.jackson.databind.ObjectMapper();
public String writeValue(Object value) {
try {
return mapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public <T> T readValue(String value, Class<T> valueType) {
try {
return mapper.readValue(value, valueType);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
But, no examples show where it is best to do this in a Spring Boot API project.
I tried to set it up in the main class method, but I am getting an error that 'setObjectMapper' cannot be resolved. I also tried to do this in the controller but I get the same error.
My Gradle deps for these two libraries are:
// https://mvnrepository.com/artifact/com.mashape.unirest/unirest-java
compile group: 'com.mashape.unirest', name: 'unirest-java', version: '1.4.5'
compile 'com.fasterxml.jackson.core:jackson-databind:2.10.1'
Can anyone show me how to use the Jackson object mapper with Unirest in a Spring Boot API project as I have been googling and reading docs for two days now. Would appreciate some help.
Thank you in advance
You have several issues here:
The version of unirest you're using (1.4.5) does not contain the feature to configure object mapper. This feature was added later (github PR). So you should update to the latest version available at maven central - 1.4.9. This alone will fix your compilation problem.
You can keep your Unirest configuration code in the main method. However if you want to use not default jackson ObjectMapper(), but the one from the spring context, then it's better to create something like a fake spring bean to inject ObjectMapper:
#Configuration
public class UnirestConfig {
#Autowired
private com.fasterxml.jackson.databind.ObjectMapper mapper;
#PostConstruct
public void postConstruct() {
Unirest.setObjectMapper(new ObjectMapper() {
public String writeValue(Object value) {
try {
return mapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public <T> T readValue(String value, Class<T> valueType) {
try {
return mapper.readValue(value, valueType);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
}
Other than that it looks this library changed the package name. Now it's com.konghq. You might want to consider updating, but library API might have changed.
Upd: for the latest version
compile group: 'com.konghq', name: 'unirest-java', version: '3.1.04'
the new API is Unirest.config().setObjectMapper(...)

Why do JAXB marshall operations have 60% lock time on Constructor.newInstance?

We are analyzing our springboot MQ listner application in order to evaluate performances. During method hotspots analysis we notice JAXB library spends 60% in lock time calling Constructor.newInstance.
We use this code in order to create constructur and to unmarshal our input bytes
JAXBContext context = JAXBContext.newInstance(ApplicationData.class);
ApplicationData aData = (ApplicationData) context.createUnmarshaller()
.unmarshal(new StringReader(new String(input)));
We call this code snippet every time we read a new message from our MQ queue. It should be a singleton by design, but: shoulde we create it once and use the same context? Maybe in a static way?
Thanks to all.
I post the solution.
We solve the lock time performace using JAXBContext as a singleton
public class JAXBContextCustom {
private static JAXBContext instance;
private static Logger logger = LoggerFactory.getLogger(JAXBContextCustom .class);
private JAXBContextCustom () {
}
public static synchronized JAXBContext initContext() {
try {
if (instance == null)
instance = JAXBContext.newInstance(ApplicationData.class);
} catch (JAXBException e) {
e.printStackTrace();
logger.error("Error instantiating JAXB context");
}
return instance;
}
}
In a second stage, as suggested by #M.Deinum, we will try to use Spring Jaxb2 to handle unmarshalling.

Java stream: Generate objects directly from an input file and save the objects with Spring Data

I'll generate for each line from an input file a Foo object and save in the next step all the objects in the database (Spring Data JPA).
//read file into stream
try (Stream<String> stream = Files.lines((path), Charset.forName("ISO-8859-1"))) {
Stream<Foo> rStream = stream.map(line -> new Foo(line));
rStream.forEach(line -> fooRepository.save(line));
} catch (IOException e) {
e.printStackTrace();
}
I received an Unhandled exception: java.lang.Exception, because the constructor of the Foo class can propagate an exception from the MyParser class:
public Foo(String row) throws Exception {
String split[] = StringUtils.split(row, "Ú");
field = MyParser.getInt(split[0]);
}
Is it possible to use the Java stream API anyway? Maybe with only one awesome stream? Somethings like this:
stream.map(Foo::new).forEach(foo -> fooRepository.save(foo));
I use Java 8 with Spring Boot 1.5.8.
If you can edit the class, why not simply throw a RuntimeException instead of throwing an Exception. If the API that you use still throws Exception you can just wrap it into:
catch(Exception e){
throw new RuntimeException(e);
}
Then you can simplify it to :
stream.map(Foo::new).forEach(fooRepository::save)

ExecutorService for Runtime.exec in Spring Boot the right way

I want to use Java ExecutorService in a Spring Boot application.
Multiple module of the application is called as #Scheduled.
This module calls a Process to get a result from an external application using Runtime.exec. The process is supposed to get a result which is processed by java
This method can be called as part of a Scheduled thread as well as part of a request and response which can be called 24/7 . Multiple instances of the method can be running at a time.
Is it optimum to use ExecutorService defined as a local variable like this or some other method is recommended.
The requirement is that Java should not be infinitely waiting to get a result. It should be timed out.
Here is the method called
public String getExternalInformation(String applicationPath, String command, int noOfTries)
{
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future;
boolean taskExecuted=false;
int trialNumber=0;
String response = "";
while((!taskExecuted)&&(trialNumber<noOfTries))
{
trialNumber++;
log.info("Starting Trial: "+trialNumber);
future= executor.submit(new TestProcessTask(applicationPath,command));
try {
System.out.println("Started Information Fetching ");
response=future.get(3, TimeUnit.MINUTES);
taskExecuted =true;
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Timed out!");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdownNow();
return response;
}
The call() method of the TestProcessTask will call the Runtime.exec and parse the returning OutputStream.
I implemented Async in Spring as suggested by M. Deinum
Using the same Future methods and got it working.,

Exception handling using hibernate template in Spring framework

I am using Spring with Hibernate in my project.There are many methods written in DAO implementation java file and every method is using the same try/catch/finally lines of code which seem redundant to me.
I am told to optimize/refactor the code since the file LOC exceeds 10k.I read somewhere that using HibernateDaoSupport we need not to worry about exceptions or closing the session. It will be taken care of by Spring itself.
Could somebody please help me how to proceed or do the needful or any better way to handle exceptions?I am pasting below code of one method in DAO layer.
public class CSDDaoImpl extends HibernateDaoSupport implements CSDDao {
public Deal getDealStructure(long dealId) throws CSDServiceException {
Session session = null;
try {
session = getSession();
Deal deal = (Deal) session.createCriteria(Deal.class).add(
Restrictions.eq("dealId", dealId)).uniqueResult();
return deal;
} catch (DataAccessResourceFailureException darfex) {
String message = "Failed to retrieve the deal object.";
CSDServiceException ex = new CSDServiceException(message, darfex);
ex.setStackTrace(darfex.getStackTrace());
ex.setErrorCode(Constants.DATA_ACCESS_FAILURE_EXP);
ex.setMessageToUser(message);
throw ex;
} catch (IllegalStateException isex) {
String message = "Failed to retrieve the deal object.";
CSDServiceException ex = new CSDServiceException(message, isex);
ex.setStackTrace(isex.getStackTrace());
ex.setErrorCode(Constants.ILLEGAL_STATE_EP);
ex.setMessageToUser(message);
throw ex;
} catch (HibernateException hbex) {
String message = "Failed to retrieve the deal object.";
CSDServiceException ex = new CSDServiceException(message, hbex);
ex.setStackTrace(hbex.getStackTrace());
ex.setErrorCode(Constants.HIBERNATE_EXP);
ex.setMessageToUser(message);
throw ex;
} finally {
if (session != null && session.isOpen()) {
try {
session.close();
} catch (HibernateException hbex) {
log.error("Failed to close the Hibernate Session.", hbex);
hbex.printStackTrace();
CSDServiceException ex = new CSDServiceException(
"Failed to close the Hibernate Session.", hbex);
ex.initCause(hbex.getCause());
ex.setStackTrace(hbex.getStackTrace());
throw ex;
}
}
}
}
}
The best approach of handling exceptions is i believe through writing an Exception Interceptor to intercept all your DAO calls and you can catch the ones you only need in your application and wrap it with your own custom application specific exceptions.
You definitely do not need to work directly with session once an exception is thrown. That would defeat the purpose of using HibernateDaoSupport and Spring.
Have a look at this link : http://static.springsource.org/spring/docs/current/spring-framework-reference/html/classic-spring.html
Hope that helps.

Resources