Java XML, The number of formal and actual parameters differs, or an unwrapping conversion has failed - java-8

When requesting data from endpoint with accept: application/xml I keep getting the following error:
javax.xml.bind.MarshalException
- with linked exception: [Exception [EclipseLink-27] (Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3):
org.eclipse.persistence.exceptions.DescriptorException Exception
Description: Trying to invoke the method [getSurveyid] on the object
[com.on24.ejb.mapping.SurveyQuestion]. The number of actual and
formal parameters differs, or an unwrapping conversion has failed.
Internal Exception: java.lang.IllegalArgumentException: object is not
an instance of declaring class Mapping:
org.eclipse.persistence.oxm.mappings.XMLDirectMapping[surveyid-->surveyid/text()]
Descriptor: XMLDescriptor(com.on24.ejb.mapping.Survey -->
[DatabaseTable(survey)])]
The response works fine when accept: application/json so I know it can't be a problem extracting the info from DB; I just haven't been able to solve this issue so any help will be greatly appreciated.
DTOs involved:
#XmlRootElement
#XmlType (propOrder={"surveyid",
"surveyquestions"})
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class Survey {
private Long surveyid;
private List<SurveyQuestion> surveyquestions;
public Survey(){}
public Long getSurveyid() {
return surveyid;
}
public void setSurveyid(Long surveyid) {
this.surveyid = surveyid;
}
#XmlElementWrapper(name="surveyquestionslist")
#XmlElement(name="surveyquestion")
public List<SurveyQuestion> getSurveyquestions() {
return surveyquestions;
}
public void setSurveyquestions(List<SurveyQuestion> surveyquestions) {
this.surveyquestions = surveyquestions;
}
}
And
#XmlRootElement
#XmlType (propOrder={"surveyquestionid",
"surveyquestion",
"surveyanswers"})
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class SurveyQuestion {
private Long surveyquestionid;
private String surveyquestion;
private List<String> surveyanswers;
public SurveyQuestion(){}
public Long getSurveyquestionid() {
return surveyquestionid;
}
public void setSurveyquestionid(Long surveyquestionid) {
this.surveyquestionid = surveyquestionid;
}
public String getSurveyquestion() {
return surveyquestion;
}
public void setSurveyquestion(String surveyquestion) {
this.surveyquestion = surveyquestion;
}
#XmlElementWrapper(name="surveyanswerslist")
#XmlElement(name="surveyanswer")
public List<String> getSurveyanswers() {
return surveyanswers;
}
public void setSurveyanswers(List<String> surveyanswers) {
this.surveyanswers = surveyanswers;
}
}
I've tried several thinks from refactoring to use XmlAccessType.PUBLIC_MEMBER, XmlAccessType.FIELD, XmlAccessType.PROPERTY but no success there.
I'd really like to understand why this error is generated. If more info is need I'll add it as per asked for, thanks.

Related

Sonarqube not finding possible null pointer exception

In the below code, Why sonarqube is not finding possible null pointer exception in "updateData" method?
public class PropertyObject extends LinkedHashMap<String, Object> {
/**
* Unique serialization id.
*/
private static final long serialVersionUID = 4789053897514939L;
}
public class BaseObject extends PropertyObject {
#JsonProperty("_id")
public String getId() {
return String.valueOf(this.get("_id"));
}
#JsonProperty("_id")
public void setId(Object id) {
this.put("_id", String.valueOf(id));
}
public String getName() {
return (String) this.get("name");
}
public void setName(String name) {
this.put("name", name);
}
}
private void updateData(BaseObject baseObject) {
List<Map<String, String>> link = (List<Map<String, String>>) baseObject.get("ratioMap");
for (Map<String, String> linkmap : link) {
}
}
}
I can see potential null pointer exception in updateData method in line number 2.
Is there any way by which I can make sonarqube to find these issues by itself?
First of all Sonar is a static code analysis tool. It depends on simple declarations to look for possible NPEs. Second I assume that you have an active rule for detecting possible NullPointer dereferences.
Last but not least I think that it would not detect NPEs in private methods which is not called...

unable to bind request parameters to the object in spring mvc?

Hi I am having an angular ui which consumes rest api's provided by a spring boot application. from the angular ui i am issuing a GET rest api call , however the request parameters are not getting binded to the object. the following is my GET request.
curl -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjYW1wYWlnbm1hbmFnZXJAbG9jYWxob3N0IiwiYXV0aCI6IlJPTEVfQ0FNUEFJR05fTUFOQUdFUiIsImV4cCI6MTU1ODE4MzAyM30.OHSqVZ5c9-44SyyB_ykFqf9xC-06UvSv-F7UYLvrrK_YNJrqF3Mvuv8zvTrBqdMXRMBdCQNmitVQ38zdZxj3Tg" http://localhost:8080/api/campaigns/unpaginated?statuses=357632f0-1afd-4af2-a8f2-3b964884bfb3&statuses=2f02e5f0-2d56-4583-a9db-f962becbd5f9&accounts=e15965cf-ffc1-40ae-94c4-b450ab190222
The following is my RestController named CampaignResource & request method
getAllCampaignsUnpaginated
#RestController
#RequestMapping("/api")
public class CampaignResource {
/**
* GET /campaigns : get all the campaigns unpaginated.
*
* #return the ResponseEntity with status 200 (OK) and the list of campaigns in body
*/
#GetMapping("/campaigns/unpaginated")
#Timed
#Secured({AuthoritiesConstants.GLOBAL_ADMIN, AuthoritiesConstants.ACCOUNT_ADMIN, AuthoritiesConstants.CAMPAIGN_MANAGER, AuthoritiesConstants.TEAM_MEMBER})
public ResponseEntity<List<DropdownDTO>> getAllCampaignsUnpaginated(CampaignFilterRequest filter) {
log.debug("REST request to get all Campaigns");
return ResponseEntity.ok().body(campaignService.findAll(filter));
}
}
the following is my CampaignFilterRequest class to which i want to bind my request parameters .
import com.google.common.collect.Lists;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;
public class CampaignFilterRequest {
private ZonedDateTime minStartDate;
private ZonedDateTime maxEndDate;
private List<UUID> types = Lists.newArrayList();
private List<UUID> createdBy = Lists.newArrayList();
private List<UUID> statuses = Lists.newArrayList();
private List<UUID> accounts = Lists.newArrayList();
public ZonedDateTime getMinStartDate() {
return minStartDate;
}
public void setMinStartDate(ZonedDateTime minStartDate) {
this.minStartDate = minStartDate;
}
public ZonedDateTime getMaxEndDate() {
return maxEndDate;
}
public void setMaxEndDate(ZonedDateTime maxEndDate) {
this.maxEndDate = maxEndDate;
}
public List<UUID> getStatuses() {
return statuses;
}
public void addStatus(UUID status) {
this.statuses.add(status);
}
public List<UUID> getTypes() {
return types;
}
public void setTypes(List<UUID> types) {
this.types = types;
}
public void addType(UUID type) {
this.types.add(type);
}
public List<UUID> getCreatedBy() {
return createdBy;
}
public void setCreatedBy(List<UUID> createdBy) {
this.createdBy = createdBy;
}
public void addCreatedBy(UUID createdBy) {
this.createdBy.add(createdBy);
}
public List<UUID> getAccounts() {
return accounts;
}
public void addAccount(UUID accounts) {
this.accounts.add(accounts);
}
public void setAccounts(List<UUID> accounts) {
this.accounts = accounts;
}
}
I am able to put a debug on the getAllCampaignsUnpaginated and i can see the statuses and accounts are empty . !!!
appreciate any help
thanks a lot.
You need setter methods for the collections as a collection object instead of a per object basis. You have
public void addStatus(UUID status) {
this.statuses.add(status);
}
But spring doesn't know how to set the uuids, if you add a setter for the entire collection it will work, for example
public void setStatuses(List<UUID> statuses) {
this.statuses = statuses;
}
Adding to this i would also suggest you create a constructor which contains all of the fields of the class that you want to set. That way you don't need setters and the class will contain less boilerplate.

Unable to show XML data

Hi my need is to show both xml and json data .
I am able to see this in local by JaxB but unable to see same code in server.
When ever I deploy that to server I got this error.
I don't know how to solve this error.
Unable to solve this, Tried a lot but Nothing happened , in local everything is fine, but when it comes to server it shows different exception.
Error 500: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Could not instantiate JAXBContext for class [class com.rest.model.ExerciseInstructionsList]: null; nested exception is javax.xml.bind.JAXBException - with linked exception: [com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Class has two properties of the same name "exerciseList" this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.getExerciseList()
at com.rest.model.ExerciseInstructionsList this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.exerciseList at com.rest.model.ExerciseInstructionsList ]
My Controller IS
#Controller
#RequestMapping("/")
public class ExerciseController {
#Autowired
private ExerciseService exerciseService;
private static final Logger logger = LoggerFactory.getLogger(ExerciseController.class);
#Consumes
#Produces
#RequestMapping(value=OaesRestURIConstants.GET_EXERCISE_ALL,method=RequestMethod.GET,produces={"application/json"})
public #ResponseBody List<ExerciseInstructions> getAllExercise()throws Exception{
logger.info("Start getAllExercises.");
System.out.println("<<<<<<<<<<<<<<<<<--------------Coming Inside List Exercise Controller----------->>>>>>>>>>>");
List<ExerciseInstructions> listExercise = new ArrayList<ExerciseInstructions>();
//ExerciseInstructionsList exe = new ExerciseInstructionsList();
/*This list contains Exercise Instructions Data*/
listExercise = exerciseService.getAllExercise();
/*here i kept the list in ExerciseInstructionsList list so that i can fetch xml data also and can show the list.*/
//exe.setExerciseList(listExercise);
return listExercise;
}
#RequestMapping(value=OaesRestURIConstants.GET_EXERCISE_XML_ALL,method=RequestMethod.GET,produces={"application/xml"})
public #ResponseBody ExerciseInstructionsList getAllXmlExercise()throws Exception{
logger.info("Start getAllExercises.");
System.out.println("<<<<<<<<<<<<<<<<<--------------Coming Inside List Exercise Controller----------->>>>>>>>>>>");
List<ExerciseInstructions> listExercise = new ArrayList<ExerciseInstructions>();
ExerciseInstructionsList exeList = new ExerciseInstructionsList();
/*This list contains Exercise Instructions Data*/
listExercise = exerciseService.getAllExercise();
/*here i kept the list in ExerciseInstructionsList list so that i can fetch xml data also and can show the list.*/
exeList.setExerciseList(listExercise);
return exeList;
}
#RequestMapping(value=OaesRestURIConstants.EXERCISE_SAVE,method=RequestMethod.POST)
public #ResponseBody ExerciseInstructions saveExercise(#RequestBody ExerciseInstructions exerciseInstructions)throws Exception{
logger.info("Start saveExercise.");
exerciseService.saveExercise(exerciseInstructions);
return exerciseInstructions;
}
//#Consumes({"application/xml","application/json"})
// #Produces({"application/xml","application/json"})
#RequestMapping(value=OaesRestURIConstants.GET_EXERCISE_ID,method=RequestMethod.GET,produces={"application/xml","application/json"})
public #ResponseBody ExerciseInstructions getExerciseById(#PathVariable("id") String exerciseId ) throws Exception{
logger.info("Start getExerciseById. ID="+exerciseId);
ExerciseInstructions exercise = null;
try {
exercise = exerciseService.getExerciseById(exerciseId);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Coming Here>>>>>>>>>>>"+exercise);
return exercise;
//return exerciseService.getExerciseById(exerciseId);
}
#RequestMapping(value=OaesRestURIConstants.EXERCISE_DELETE,method=RequestMethod.PUT)
public #ResponseBody ExerciseInstructions deleteById(#PathVariable("id") String exerciseId) throws Exception{
logger.info("Start deleteExercise.");
exerciseService.deleteExercise(exerciseId);
return null;
}
}
My Model class is :
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class ExerciseInstructions {}
My Model List Class Is :
#XmlRootElement(name="exerciseInstructions")
//#XmlSeeAlso({ExerciseInstructions.class})
#XmlAccessorType(XmlAccessType.FIELD)
public class ExerciseInstructionsList {
public List<ExerciseInstructions> exerciseList;
public List<ExerciseInstructions> getExerciseList() {
return exerciseList;
}
public void setExerciseList(List<ExerciseInstructions> exerciseList) {
this.exerciseList = exerciseList;
}
}
So can anyone help me in this.
I want to fetch and see both xml and json.
When you carefully read the error-message you see the reason: (I formatted and highlighted the message for better readability)
IllegalAnnotationExceptions Class has two properties of the same name "exerciseList"
this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.getExerciseList() at com.rest.model.ExerciseInstructionsList
this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.exerciseList at com.rest.model.ExerciseInstructionsList
So the program complains that your class ExerciseInstructionsList has two properties which can be mapped to exerciseList, these are getExerciseList() and exerciseList.
To fix this you can declare exerciseList as private.
#XmlRootElement(name="exerciseInstructions")
#XmlAccessorType(XmlAccessType.FIELD)
public class ExerciseInstructionsList {
private List<ExerciseInstructions> exerciseList;
public List<ExerciseInstructions> getExerciseList() {
return exerciseList;
}
public void setExerciseList(List<ExerciseInstructions> exerciseList) {
this.exerciseList = exerciseList;
}
}

MOXyJsonProvider not working

In my REST applications (under GlassFish 4.1.2) I want to convert POJOs to JSON and back again. The examples all make it look easy but I am missing something.
Here is my application:
#ApplicationPath("/")
public class RootApp extends Application {
#Override
public Set<Class<?>> getClasses() {
HashSet set = new HashSet<Class<?>>();
set.add(HelloWorld.class);
return set;
}
#Override
public Set<Object> getSingletons() {
HashSet set = new HashSet<Object>();
MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
moxyJsonProvider.setFormattedOutput(true);
set.add(moxyJsonProvider);
return set;
}
}
And here is the Resource:
#Path("helloworld")
public class HelloWorld {
private static int counter = 1;
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getInevitableMessage() {
JsonHello hj = new JsonHello("Hello World", counter++);
return Response.ok(hj).build();
}
}
And last and least is the POJO to convert to and from JSON:
public class JsonHello {
private int count;
private String message;
public JsonHello(String message, int count) {
this.message = message;
this.count = count;
}
public int count() { return count; }
public void count(int value) { count = value; }
public String message() { return message; }
public void message(String value) { message = value; }
}
I am referring to the tagged answer in this thread. When I attempt to access "/helloworld" it pitches the following exception:
org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
This application works if the resource just returns a string. There is nothing in the web.xml file since I am letting Glassfish set the application via its decorators.
Any idea what I am missing here?
I ended up solving the problem using the direction that #peeskillet suggested. MOXyJsonProvider is unneeded.
One problem that is hard to address is that almost all the examples on the web assume you are configuring your Servlet with a web.xml file, which I am not. All the configuration I do is from inside the Application object. The Jersey documentation does not make this very clear. What ends up working is this:
#Override
public Set<Class<?>> getClasses() {
HashSet set = new HashSet<Class<?>>();
set.add(JacksonFeature.class);
set.add(MyObjectMapperProvider.class);
set.add(Home.class);
set.add(HelloWorld.class);
return set;
}
At this point the REST resources can produce and consume various POJOs which are transcoded into JSON perfectly and without any effort.
Instead of just deleting this question I will put this answer here in hopes of saving someone the amount of time I spent finding this out.

Spring Validation rejectValue for inherited fields

I get Exception
org.springframework.beans.NotReadablePropertyException: Invalid property 'entries[0].reason' of bean class [my.company.data.SDROrder]: Bean property 'entries[0].reason' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
from the following code snippet:
Errors errors = new BeanPropertyBindingResult(new SDROrder(), "sdr");
orderValidator.validate(order, errors);
for validator:
public class OrderValidator implements Validator
{
#Override
public boolean supports(Class<?> clazz)
{
return Order.class.isAssignableFrom(clazz);
}
#Override
public void validate(final Object target, final Errors errors)
{
errors.rejectValue("entries[0].reason", "Wrong Reason");
}
}
where we have such data hierarchy
public class Order
{
private List<AbstractOrderEntry> entries;
public List<AbstractOrderEntry> getEntries()
{
return entries;
}
public void setEntries(List<AbstractOrderEntry> entries)
{
this.entries = entries;
}
}
public class SDROrder extends Order
{
}
public class AbstractOrderEntry
{
}
public class SDROrderEntry extends AbstractOrderEntry
{
private String reason;
public String getReason()
{
return reason;
}
public void setReason(String reason)
{
this.reason = reason;
}
}
Please see working example here: here
Update 1: Just to clarify. The problem is I try to rejectValue on object that has Collection of objects where each element has specific attribute at Runtime but has not it at Compile time. Spring uses Bean's properties to resolve these fields and can't find inherited attribute. The question is: can I explain Spring to resolve inherited fields somehow?
I found the solution here.
The trick is at
org.springframework.validation.Errors.pushNestedPath(String)
and
org.springframework.validation.Errors.popNestedPath()
methods.
The correct validation should be done as follow:
errors.pushNestedPath("entries[0]");
errors.rejectValue("reason", "Wrong Reason");
errors.popNestedPath();

Resources