I am trying to create a webservice which takes a VO and VO contains a parameter of type Map. I wrote this simple Service and trying to create the webservice out of it. While creating the webservice I am getting exception that its not supported.
public MyVO myService(MyVO vo) {
return vo;
}
public class VO{
private String name;
private Map<String, Serializable> paramsMap;
}
Error Which I am getting :
The field or property on the value type used via the service class has a data type, "java.util.Map", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
I am not sure what's wrong with this. Any help or work around?
thanks in advance.
This link shows the data types supported by JAX-RPC 1.1 and Map (and all its subclasses aren't supported).
JAX-RPC 1.1 Specification, section 5.1.3 states:
Other standard Java classes (for
example: classes in the Java
Collection Framework) are mapped using
pluggable serializers and
deserializers. Refer to the chapter 15
(“Extensible Type Mapping”) for more
details on the pluggable serializers
and deserializers.
One workaround is to have an array of key/value pair JavaBean that you can pass through a parameter.
Example:
public final class KVPair<T> implements Serializable {
private String key;
private T value;
//Getters and setters
}
And have a service that has a map of KVPair.
service.consume(KVPair[] map);
IBM DeveloperWorks shows examples of mapping arrays as a Complex Type in WSDL.
Related
UUID
A universally unique identifier (UUID) is a 128-bit value. Represented in Java by the java.util.UUID class.
Hex string
For display and for serialization, it is canonically formatted as a 36-character hexadecimal string arranged in five groups delimited by a hyphen. For example:fd95cb46-8ec3-11e8-9eb6-529269fb1459
When serializing using the Java-standard XML & JSON APIs I expect this hex string. Worked for XML, but failed for JSON. I am using no annotations of any kind for either XML or JSON. My simple POJO knows nothing of XML nor JSON.
XML = success 👍
When I produce XML using the standard XML-binding framework of JSR 222: JavaTM Architecture for XML Binding (JAXB) 2.0, success. I get the hex string as expected. See last element of this snippet:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<panel>
<connected>3.4kVA</connected>
<fedFrom>PANEL 'EHE1' & ATS-EM</fedFrom>
<grounding>ground bus</grounding>
<id>89d14b92-35ae-4c0c-b61d-ea8dbdeb324b</id>
JSON = fail 👎
When I run that same panel object through the standard JSON-binding framework of JSR 367: JavaTM API for JSON Binding (JSON-B), failure. Instead of the expected hex string, I get numbers.
{"connected":"3.4kVA","fedFrom":"PANEL 'EHE1' & ATS-EM","grounding":"ground bus","id":{"leastSignificantBits":-5323841289984462261,"mostSignificantBits":-8515942329042973684},
If you scroll over, you will see the UUID named id is presented as a pair of numbers rather than as a hex string:
"id":{"leastSignificantBits":-5323841289984462261,"mostSignificantBits":-8515942329042973684}
Is there some way to get the JSON binding to behave as the XML binding does? I want the hex string, not a pair of 64-bit numbers.
And of course this marshaled value should work when unmarshaled, re-hydrated into a Java object.
The JSON-B spec makes no mention of the UUID type, so it's up to the implementation whether or not it provides a (de)serializer out of the box. However, if you are using Eclipse Yasson (the JSON-B ref impl), it does provide a UUID (de)serializer by default. I'm not sure what other JSON-B impls (such as Apache Johnzon) provide by default.
If you are using Yasson, I would recommend opening a bug on their GitHub repo, because this should work.
Custom way
If you are using a JSON-B implementation that does not provide UUID adapters by default, you can create and register your own type adapter:
public static class MyUUIDAdapter implements JsonbAdapter<UUID, String> {
#Override
public String adaptToJson(UUID obj) throws Exception {
return obj.toString();
}
#Override
public UUID adaptFromJson(String obj) throws Exception {
return UUID.fromString(obj);
}
}
The easiest way to register the adapter is when you create the Jsonb instance:
Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new MyUUIDAdapter()));
However, if you don't control instantiation of your Jsonb instance (e.g. JAX-RS is doing it under the covers) you can annotate the field/method to use the adapter on:
public class Panel {
#JsonbTypeAdapter(MyUUIDAdapter.class)
public UUID id;
}
In my REST application developed using SpringBoot and Angular, I need to send a REST request to SpringBoot back end in order to save a object into the database.
In the front end, user fills up a form and submits. Following is the interface from which a object is created in order to be sent to the backend as a REST call.
export interface TenderToPost{
id: number;
name: string;
description: string;
images: File[];
referenceNumber: string;
}
The backend should deserialize the above object to a object of Following class in Java.
public class TenderDTO implements Serializable{
private long id;
private String name;
private String description;
private List<MultipartFile> images;
private String referenceNumber;
// default constructor
// geters and setters
}
As shown above, I need to accept the File sent from frontend as a MultipartFile.
However, when the request is sent from the front end, Jackson gives me the error
Can not construct instance of
org.springframework.web.multipart.MultipartFile: abstract types either
need to be mapped to concrete types, have custom deserializer, or
contain additional type information
I am aware that that this error comes since I have used MultipartFile interface as the type of my images list.
What I thought of as the solution for this, is letting Jackson know to what type the list should be deserialized into using an annotation. So, I used following
#JsonDeserialize(contentAs = CommonsMultipartFile.class)
private List<MultipartFile> images;
CommonsMultipartFile is an implementation of MultipartFile. That is why I used it.
Now I get the following error.
Can not construct instance of
org.springframework.web.multipart.commons.CommonsMultipartFile: no
suitable constructor found, can not deserialize from Object value
(missing default constructor or creator, or perhaps need to add/enable
type information?)
Do I need to change the setter for the images list? Or is my whole approach incorrect?
Kindly show me the way how I should correct this.
Try to use #JsonPropertyDescription to construct object.
#JsonPropertyDescription example
I have a WebService that send a List of Vehicle to the Web Service Client, the Vehicle is implemented as follow :
public class Vehicle implements Serializable{
private static final long serialVersionUID = -8169481181178317205L;
private final String id;
private final LocalDate depositDate;
private final double price;
private final ArrayList<Integer> scores = new ArrayList<>();
private final ArrayList<String> comments = new ArrayList<>();
private Optional<Renter> renter = Optional.empty();
private int rentalNumber = 0;
}
As you can see, the vehicle object contains 2 fields wich are ArrayList. When I want to create the Web Service I have multiple warning telling me that Vehicle (which is the only object I want to send over the network) and other object aren't respecting the JAX-RPC convention and may not get sent properly.
How to get rid of these warnings ? Is this an obligation ?
The first solution I implemented was to transform the list into an array but is there anything else ?
EDIT 5: The problem comes the fact to add a parameter in the method i want to use for the web service.I tried to add a method like this one :
public StatePayment lol(int lol){
return StatePayment.DENIED;
}
And the Web Services Creation software returned me the same error. Isn't that possible to add a method with parameters ?
EDIT4:I created a fake method just to test what was the problem. It seems that when i had the parameter in the method signature i have the precedent error.
//Not working code
public StatePayment lol(Buyer buyer){
return StatePayment.DENIED;
}
//Working code
public StatePayment lol(Buyer buyer){
return StatePayment.DENIED;
}
I guess the problem comes from buyer but i can't get what could it be.
EDIT 3: When i want to create the webService by "new->WebService-> Selecting the methods.
I have the following error:
IWAB0398E Error in generating WSDL from Java: >java.lang.IllegalStateException: Error looking for paramter names in >bytecode: unexpected bytes in file
Is this a serialisation problem ?
The error happens when i select this method:
public int proceedToPayment(Buyer buyer) {
//Calcul du prix total du shoppingCart
long totalPrice = 0;
for(Vehicle v : buyer.getShoppingCart()) {
totalPrice += v.getPrice();
}
Bank buyerBank = buyer.getBank();
//Convertir totalPrice en euros vers la monnaie du Buyer.
if(buyerBank.bankTransaction(totalPrice, buyer) == StatePayment.DENIED) {
return 0;
}
removeShoppingCartFromBDD(buyer.getShoppingCart());
return 1;
}
EDIT 2: To be more clear, my principal question is. Am i forced to get rid of all these warning messages knowing that the only object that i will send over the network are Vehicle and the ones that are inside Vehicle (Renter)
EDIT 1: The warning message
The service class "MlvDataBaseImpl" does not comply to one or more
requirements of the JAX-RPC 1.1 specification, and may not deploy or
function correctly.
The method "exportObject" on the service class "MlvDataBaseImpl" is
overloaded. Overloaded methods are allowed by chapter 5.5.5 of the
JAX-RPC 1.1 specification, however, some JAX-RPC 1.1 compliant tools
may not allow overloaded methods or may generate WSDL with overloaded
operations as contrary to rule R2304 of the WS-I Basic Profile.
The value type "MlvDataBase" used via the service class
"MlvDataBaseImpl" does not have a public default constructor. Chapter
5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise, a JAX-RPC 1.1 compliant Web
service engine may be unable to construct an instance of the value
type during deserialization.
The value type "Renter" used via the service class "MlvDataBaseImpl"
does not have a public default constructor. Chapter 5.4 of the JAX-RPC
1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web service engine may
be unable to construct an instance of the value type during
deserialization.
The value type "Vehicle" used via the service class
"MlvDataBaseImpl" does not have a public default constructor. Chapter
5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web
service engine may be unable to construct an instance of the value
type during deserialization.
The value type "Buyer" used via the service class "MlvDataBaseImpl"
does not have a public default constructor. Chapter 5.4 of the JAX-RPC
1.1 specification requires a value type to have a public default constructor, otherwise, a JAX-RPC 1.1 compliant Web service engine may
be unable to construct an instance of the value type during
deserialization.
The method "registerVehicle" on the service class "MlvDataBaseImpl"
uses a data type, "java.time.LocalDate", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "getRentableVehicles" on the service class
"MlvDataBaseImpl" uses a data type, "java.util.List", that is not
supported by the JAX-RPC specification. Instances of the type may not
serialize or deserialize correctly. Loss of data or complete failure
of the Web service may result.
The method "clone" on the service class "MlvDataBaseImpl" uses a
data type, "java.lang.Object", that is not supported by the JAX-RPC
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.server.RemoteStub", that is not supported
by the JAX-RPC specification. Instances of the type may not serialize
or deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.Remote", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.Remote", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.Remote", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.Remote", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.Remote", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.server.RMIClientSocketFactory", that is
not supported by the JAX-RPC specification. Instances of the type may
not serialize or deserialize correctly. Loss of data or complete
failure of the Web service may result.
The method "exportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.server.RMIServerSocketFactory", that is
not supported by the JAX-RPC specification. Instances of the type may
not serialize or deserialize correctly. Loss of data or complete
failure of the Web service may result.
The method "unexportObject" on the service class "MlvDataBaseImpl"
uses a data type, "java.rmi.Remote", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "setLog" on the service class "MlvDataBaseImpl" uses a
data type, "java.io.OutputStream", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "getLog" on the service class "MlvDataBaseImpl" uses a
data type, "java.io.PrintStream", that is not supported by the JAX-RPC
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The method "getRef" on the service class "MlvDataBaseImpl" uses a
data type, "java.rmi.server.RemoteRef", that is not supported by the
JAX-RPC specification. Instances of the type may not serialize or
deserialize correctly. Loss of data or complete failure of the Web
service may result.
The method "toStub" on the service class "MlvDataBaseImpl" uses a
data type, "java.rmi.Remote", that is not supported by the JAX-RPC
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The method "toStub" on the service class "MlvDataBaseImpl" uses a
data type, "java.rmi.Remote", that is not supported by the JAX-RPC
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The method "equals" on the service class "MlvDataBaseImpl" uses a
data type, "java.lang.Object", that is not supported by the JAX-RPC
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The service class "MlvDataBaseImpl" does not have a public default
constructor. Chapter 10.1 of the JAX-RPC 1.1 specification requires a
service class to have a public default constructor, otherwise a
JAX-RPC 1.1 compliant Web service engine may be unable to construct an
instance of the service class to handle an incoming request message.
The field or property "declaringClass" on the value type
"java.lang.Enum" used via the service class "MlvDataBaseImpl" has a
data type, "java.lang.Class", that is not supported by the JAX-RPC 1.1
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The field or property "depositDate" on the value type "Vehicle" used
via the service class "MlvDataBaseImpl" has a data type,
"java.time.LocalDate", that is not supported by the JAX-RPC 1.1
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The field or property "comments" on the value type "Vehicle" used
via the service class "MlvDataBaseImpl" has a data type,
"java.util.List", that is not supported by the JAX-RPC 1.1
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The field or property "scores" on the value type "Vehicle" used via
the service class "MlvDataBaseImpl" has a data type, "java.util.List",
that is not supported by the JAX-RPC 1.1 specification. Instances of
the type may not serialize or deserialize correctly. Loss of data or
complete failure of the Web service may result.
The field or property "declaringClass" on the value type
"java.lang.Enum" used via the service class "MlvDataBaseImpl" has a
data type, "java.lang.Class", that is not supported by the JAX-RPC 1.1
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
The field or property "shoppingCart" on the value type "Buyer" used
via the service class "MlvDataBaseImpl" has a data type,
"java.util.ArrayList", that is not supported by the JAX-RPC 1.1
specification. Instances of the type may not serialize or deserialize
correctly. Loss of data or complete failure of the Web service may
result.
Please look at this post JAXB annotations for nested element lists for more details, how to serialize lists.
As for the warnings, you need to search for each one in SO, there are many different subjects involved.
Using axis2's wsdl2java tool and a third-party wsdl I have generated service stub and supporting classes (data holders). Since there is a need to do post-processing of loaded data from a service, there is a need to serialize one of the data holder objects.
1) is there a standard axis2 tool / approach that can be used for the purpose?
2) since the data holder class does not implement Serializable interface what would be the easiest way of serializing the object into xml format with the ability to restore the original object?
Data binding option was used (-d jaxbri) and each field of the class in question is annotated with #XmlElement tag, e.g.:
#XmlElement(name = "ID", required = true)
protected String id;
Ok, here is how I solved it:
axis2 generated java classes set (client side) had an object called ObjectFactory. Majority of its methods create JAXBElement objects with values of fields of the class holder
I had to implement a serializable wrapper class aSerializable for the class holder, such that it uses the ObjectFactory to create the JAXBElement objects for all the fields.
some external code uses the wrapper class to create an serializable object and writes it to the output stream.
on the receiving end:
ASerializable aSerializable;
A a;
aSerializable= (ASerializable)in.readObject();
a.setID((String)aSerializable.getID().getValue());
it still looks like extra work for the pre-annotated class serialization, but better than serializing into some text format and manual type checking during deserialization.
I am trying to create a new Web Service in Eclipse (bottom up, apache axis 1, tomcat 6), but I get warnings before the attempt and then an error after.
Error:
IWAB0398E Error in generating WSDL from Java: java.lang.ClassCastException: org.apache.axis.encoding.ser.BeanSerializer cannot be cast to org.apache.axis.encoding.Serializer
Here is where I use Serializable:
public class IntegrationUtils extends Utilities implements java.io.Serializable {
private static final long serialVersionUID = 7515033201857603982L;
Summary of Warnings:
A lot of the warnings have to do with classes used by my web service class not having default constructors.
Here are the warnings:
The service class "net.abc.Indy.WebService.IntegrationUtils" does not comply to one or more requirements of the JAX-RPC 1.1 specification, and may not deploy or function correctly.
The service class "net.abc.Indy.WebService.IntegrationUtils" does not comply to one or more requirements of the JAX-RPC 1.1 specification, and may not deploy or function correctly.
The field or property "headers" on the value type "org.apache.axis.AxisFault" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.util.ArrayList", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "cause" on the value type "java.rmi.RemoteException" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Throwable", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "noClasses" on the value type "org.apache.axis.description.TypeDesc" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Class", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "noObjects" on the value type "org.apache.axis.description.TypeDesc" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Object", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "propertyDescriptorMap" on the value type "org.apache.axis.description.TypeDesc" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.util.Map", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "type" on the value type "org.apache.axis.utils.BeanPropertyDescriptor" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Class", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "actualType" on the value type "org.apache.axis.utils.BeanPropertyDescriptor" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Class", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "javaType" on the value type "org.apache.axis.description.FieldDesc" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Class", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "headers" on the value type "org.apache.axis.AxisFault" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.util.ArrayList", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The field or property "cause" on the value type "java.rmi.RemoteException" used via the service class "net.abc.Indy.WebService.IntegrationUtils" has a data type, "java.lang.Throwable", that is not supported by the JAX-RPC 1.1 specification. Instances of the type may not serialize or deserialize correctly. Loss of data or complete failure of the Web service may result.
The value type "org.w3c.dom.Element" used via the service class "net.abc.Indy.WebService.IntegrationUtils" does not have a public default constructor. Chapter 5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web service engine may be unable to construct an instance of the value type during deserialization.
The value type "org.w3c.dom.TypeInfo" used via the service class "net.abc.Indy.WebService.IntegrationUtils" does not have a public default constructor. Chapter 5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web service engine may be unable to construct an instance of the value type during deserialization.
The value type "org.apache.axis.description.TypeDesc" used via the service class "net.abc.Indy.WebService.IntegrationUtils" does not have a public default constructor. Chapter 5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web service engine may be unable to construct an instance of the value type during deserialization.
The value type "org.apache.axis.utils.BeanPropertyDescriptor" used via the service class "net.abc.Indy.WebService.IntegrationUtils" does not have a public default constructor. Chapter 5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web service engine may be unable to construct an instance of the value type during deserialization.
The value type "org.apache.axis.description.FieldDesc" used via the service class "net.abc.Indy.WebService.IntegrationUtils" does not have a public default constructor. Chapter 5.4 of the JAX-RPC 1.1 specification requires a value type to have a public default constructor, otherwise a JAX-RPC 1.1 compliant Web service engine may be unable to construct an instance of the value type during deserialization.
Thanks for any help!
You get a ClassCastException, whenever you have duplicate JARs or JAR-files with the same class-files in it. In you case it could be a different Axis version too. The problem typically occures, when your tomcat instantiates a axis-class and sends this instance to your application. Your application on the other side can uses its own jars (packaged into you WAR or EAR). And because of the posibility of a multi classloader hirarchie in a Web- or Java EE-Container you can run different webapps with there own jar-files-versions at the same server at the same time.
But how to solve it? Well, search for these classes (shown in the StackTrace) in all jars of you tomcat and your web-application and check, which one is used to instantiate Axis-Requests/-responses. The easiest solution is, to remove the relevant jar from you web application and to compile your code against the jar's of you runtime environment (your tomcat). If the tomcat-jar-versions are not usable for your case, try to patch the server-jars.
An alternative solution can be a different configuration of your web-application/server to controll the classloaders.