I'm trying to use annotations at package level but I get compilation erros from Eclipse.
I have a class Head with the following package/annotation:
#javax.xml.bind.annotation.XmlSchema (
xmlns = {
#javax.xml.bind.annotation.XmlNs(prefix = "com",
namespaceURI="http://es.indra.transporte.common"),
#javax.xml.bind.annotation.XmlNs( namespaceURI="http://www.w3.org/2001/XMLSchema")
},
namespace = "http://es.indra.transporte.common",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED
)
package es.indra.transporte.central.thalesinterface.common.beans;
I have created a package-info.java in es.indra.transporte.central.thalesinterface.common.beans folder with the above code but I'm still getting the compilation error
Package annotations must be in file package-info.java
in Head class. I'm using jdk6.
The only problem I got when trying to compile your package info was that the #XmlNs annotation was missing the prefix property.
This:
#javax.xml.bind.annotation.XmlNs( namespaceURI="http://www.w3.org/2001/XMLSchema")
Should be:
#javax.xml.bind.annotation.XmlNs(prefix="xsd", namespaceURI="http://www.w3.org/2001/XMLSchema")
The following corrected code should compile:
#javax.xml.bind.annotation.XmlSchema (
xmlns = {
#javax.xml.bind.annotation.XmlNs(prefix = "com",
namespaceURI="http://es.indra.transporte.common"),
#javax.xml.bind.annotation.XmlNs(prefix="xsd", namespaceURI="http://www.w3.org/2001/XMLSchema")
},
namespace = "http://es.indra.transporte.common",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED
)
package es.indra.transporte.central.thalesinterface.common.beans;
For an example see:
http://bdoughan.blogspot.com/2010/08/jaxb-namespaces.html
Related
I'm working on a java project where bazel is being used. I'm looking to add tink java lib in bazel but looks like com_github_google_tink is not a valid package name.
java_library(
name = "testlib",
srcs = glob(["*.java"]),
deps = [
"#com_github_google_tink",
],
visibility = ["//visibility:public"],
)```
I already referred this article https://developers.google.com/tink/install-tink but it only talks about adding java deps in maven. Can someone help ?
Are you using rules_jvm_external to get the tink dependency?
https://github.com/bazelbuild/rules_jvm_external
If not, you might try adding this or similar to your WORKSPACE file:
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "4.2"
RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("#rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
rules_jvm_external_deps()
load("#rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
rules_jvm_external_setup()
load("#rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.google.crypto.tink:tink:1.6.1",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
Then you can use the tink dependency from maven in your BUILD / BUILD.bazel file like this:
java_library(
name = "testlib",
srcs = glob(["*.java"]),
deps = [
"#maven//:com_google_crypto_tink_tink",
],
visibility = ["//visibility:public"],
)
I am trying to create the below XML document .
<?xml version="1.0" encoding="UTF-8"?>
<BCPFORMAT>
<RECORD>
<FIELD ID="1" xsi:type="CharFixed" MAX_LENGTH="4" />
</RECORD>
</BCPFORMAT>
I'm using the Java Code as below -
package com.tutorialspoint.xml;
import java.awt.List;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
public class createXmlLayout {
public static void main(String[] args) {
Document doc = new Document();
Element root = new Element("BCPFORMAT");
//RECORD Element
Element child = new Element("RECORD");
//FIELD Element
Element name = new Element("FIELD")
.setAttribute("ID", "1")
.setAttribute("xsi:type", "CharFixed")
.setAttribute("MAX_LENGTH", "4");
child.addContent(name);
root.addContent(child);
doc.addContent(root);
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
try {
outputter.output(doc, System.out);
outputter.output(doc, new FileWriter("c:\\VTG_MAPN.xml"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
But I'm getting the below error:
The name "xsi:type" is not legal for JDOM/XML attributes: XML name 'xsi:type' cannot contain the character ":".
I know I might need to use Namespace but how I'm not able to figure out.
JDOM doesn't allow you to create paths containing colons (:) that way, due to XML 1.0 specifications on : being reserved to namespaces. Check JDOM's FAQ here.
To set or create an attribute that uses a namespace you must use a function/constructor that accepts a namespace as a parameter.
In this case, you could use the following:
e.setAttribute("type", "CharFixed", Namespace.getNamespace("xsi", "xsi_uri"));
UPDATE:
We can add a namespace declaration inside one of the parents of the child (FIELD), and set the child to use this namespace for a given attribute.
Namespace namespace = Namespace.getNamespace("xsi", "xsi_uri");
root.addNamespaceDeclaration(namespace);
// ...
Element name = new Element("FIELD")
.setAttribute("ID", "1")
.setAttribute("type", "CharFixed", root.getNamespacesInScope().get(2))
.setAttribute("MAX_LENGTH", "4");
// ...
The output will be the following:
<?xml version="1.0" encoding="UTF-8"?>
<BCPFORMAT xmlns:xsi="xsi_uri">
<RECORD>
<FIELD ID="1" xsi:type="CharFixed" MAX_LENGTH="4" />
</RECORD>
</BCPFORMAT>
This feature is part of the NamespaceAware Interface
Why get(2):
if we get the inherited namespace list for the root element it will return 3 namespaces, described by the following text:
[Namespace: prefix "" is mapped to URI ""]
[Namespace: prefix "xml" is mapped to URI "http://www.w3.org/XML/1998/namespace"]
[Namespace: prefix "xsi" is mapped to URI "xsi_uri"]
Thus, index 0 is an empty namespace, index 1 is the default XML namespace and finally, index 2 is the added namespace for xsi.
Of course, we don't want to hardcode an index for the desired namespace, therefore, we could do the following to cache the desired namespace beforehand:
Namespace xsiNamespace =
root.getNamespacesInScope().stream() // Streams the namespaces in scope
.filter((ns)->ns.getPrefix().equals("xsi")) // Search for a namespace with the xsi prefix
.findFirst() // Stops at the first find
.orElse(namespace); // If nothing was found, returns
// the previously declared 'namespace' object instead.
Using the cached namespace:
// ...
.setAttribute("type", "CharFixed", xsiNamespace)
// ...
getting error in code -
#GenericGenerator(name = "hilo-gen", strategy = "guid")
#CollectionId (columns ={#Column(name = "Address_ID")},type = #Type(type="long"),generator ="guid-gen" )
private Collection<AddressClass> listAddresses = new ArrayList<AddressClass>();
and getting this error during compilation
incompatible types: org.hibernate.mapping.Column cannot be converted to javax.persistence.Column
At the top of your file you are importing
org.hibernate.mapping.Column
Instead import
javax.persistence.Column
as described in the #CollectionId javadoc.
If you need both Column classes, use the fully qualified name of the one you haven't imported to use it.
I used CXF WSDL2java to generate a server for an existing WSDL.
This gave me a SEI like that :
#WebService(targetNamespace = "http://mon.namespace.1", name = "MonWs")
#XmlSeeAlso({ObjectFactory.class})
public interface MonWs {
#WebResult(name = "Output", targetNamespace = "http://mon.namespace.1")
#RequestWrapper(localName = "maMethodePrincipale", targetNamespace = "http://mon.namespace.1", className = "MaMethodePrincipaleRequest")
#WebMethod(operationName = "maMethodePrincipale", action = "http://mon.namespace.1/MonWs/maMethodePrincipale")
#ResponseWrapper(localName = "maMethodePrincipaleResponse", targetNamespace = "http://mon.namespace.1", className = "MaMethodePrincipaleResponse")
public MaMethodePrincipaleResponse.Output maMethodePrincipale(
#WebParam(name = "Input", targetNamespace = "http://mon.namespace.1")
MaMethodePrincipaleRequest.Input Input
);
}
I created a basic implementation but when I call it on my server (hosted on tomcat, with de CXfNonSpringServlet) with soapUI (and other client) I got this kind of return :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:MaMethodePrincipaleResponse xmlns:ns1="http://mon.namespace.1">
<ns2:return xmlns="http://mon.namespace.2" xmlns:ns2="http://mon.namespace.1"/>
...
my return object field list correctly named
...
</ns2:return>
</ns1:MaMethodePrincipaleResponse>
</soap:Body>
</soap:Envelope>
my problem is the the tag "ns2:return ..." it should be name "Output" like I define in all the annotations (even in maMethodePrincipaleResponse name etc...)
So when i try to call my server with a java client I've got an error message like
javax.xml.bind.UnmarshalException: Unexpected Element (URI : "http://mon.namespace.1", local : "return"). Expected elements are <{http://mon.namespace.1}Output>
I already try a bunch of possible correction like set the soap binding to "bare" and set every partname or name to "Output" But nothing works.
What should i do to have this return parameter named "Output"?
You can try to use Interceptor.
in this link you can see how you can modify cxf response.
good luck
You are using Request/ResponseWrapper's. Thus, the names for the elements would be defined in the annotations on the fields in those classes.
I have to marshall a fragment of my root xml object :
Header header = ebicsNoPubKeyDigestsRequest.getHeader();
JAXBElement<org.ebics.h003.EbicsNoPubKeyDigestsRequest.Header> jaxbElement =
new JAXBElement<EbicsNoPubKeyDigestsRequest.Header>(
new QName("header"), EbicsNoPubKeyDigestsRequest.Header.class, header);
byte[] headerXml = JAXBHelper.marshall(jaxbElement, true);
but when I marshall ebicsNoPubKeyDigestsRequest the namespaces are not the same (in header fragment I have : xmlns:ns4="http://www.ebics.org/H003" but in ebicsNoPubKeyDigestsRequest I have xmlns="http://www.ebics.org/H003")
If I marshall the header object directly, without using JAXBElement, I have an No #XmlRootElement error
How I can have the same namespaces?
NB : I already use a NamespacePrefixMapper class :
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
#Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if (namespaceUri.equals("http://www.ebics.org/H003")) {
return "";
} else if (namespaceUri.equals("http://www.w3.org/2000/09/xmldsig#")) {
return "ds";
} else if (namespaceUri.equals("http://www.ebics.org/S001")) {
return "ns1";
} else if (namespaceUri.equals("http://www.w3.org/2001/XMLSchema-instance")) {
return "ns2";
}
return "";
}
});
EDIT : here the different package-info.java :
#javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ebics.org/H003", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.ebics.h003;
#javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ebics.org/S001", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.ebics.s001;
#javax.xml.bind.annotation.XmlSchema(namespace = "http://www.w3.org/2000/09/xmldsig#", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.w3._2000._09.xmldsig_;
Without seeing your actual XML schema, files and JAXB generated classes (and their annotations) I can only advise you to try an adapt the following example to your scenario.
Given that you have a JAXB generated class like the following:
#XmlRootElement(namespace = "http://test.com")
#XmlType(namespace = "http://test.com")
public static final class Test {
public String data;
public Test() {}
}
which is in the package test and there is a package-info.java file in it like this:
#XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED,
xmlns = #XmlNs(prefix = "", namespaceURI = "http://test.com"))
package test;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
the following code:
Test test = new Test();
test.data = "Hello, World!";
JAXBContext context = JAXBContext.newInstance(Test.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(test, System.out);
will print this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test xmlns="http://test.com">
<data>Hello, World!</data>
</test>
You can probably probably omit a the NamespacePrefixMapper implementation entirely.
Play with omitting particular namespace elements from any of the annotations and see how the output changes.
Blaise Doughan (a Java XML binding expert, probably lurking around somewhere near) has posted some info regarding this issue on his blog, see his post for some more insight.
Based on the input provided by Baptiste in chat I propose the following solution (I think this is the most painless).
Compile your schema files with XJC normally ($ xjc .). This will generate package-java.info files for each of the generated packages. I assume this schema isn't updated everyday, so you're safe to make modifications on the package-info.java files (even though there will be some line comments in those files telling you not to do it—do it anyway). If the schema gets updated and you have to re-compile it run XJC with the -npa switch, which tells it not to generate those package-info.java files automatically, so (ideally) you can't overwrite your hand-crafted files (if you use version control you can/should include these (handmade) files in the repository).
Based on the provided schema files four packages are generated, so I'll include my version of the modified package-info.java files.
#XmlSchema(namespace = "http://www.ebics.org/H000",
xmlns = #XmlNs(prefix = "ns1",
namespaceURI = "http://www.ebics.org/H000"))
package org.ebics.h000;
#XmlSchema(namespace = "http://www.ebics.org/H003",
xmlns = #XmlNs(prefix = "",
namespaceURI = "http://www.ebics.org/H003"))
package org.ebics.h003;
#XmlSchema(namespace = "http://www.ebics.org/S001",
xmlns = #XmlNs(prefix = "ns3",
namespaceURI = "http://www.ebics.org/S001"))
package org.ebics.s001;
#XmlSchema(namespace = "http://www.w3.org/2000/09/xmldsig#",
xmlns = #XmlNs(prefix = "ns2",
namespaceURI = "http://www.w3.org/2000/09/xmldsig#"))
package org.w3._2000._09.xmldsig;
After this you create your JAXBContext like this:
JAXBContext context =
JAXBContext.newInstance("org.ebics.h003:org.ebics.s001:org.w3._2000._09.xmldsig");
(I've noticed that you don't use actually use the h000 package so I've omitted it from the package name list. If it is included, then the marshalled XML's root tag will probably contain its namespace and prefix mapping, even tough it isn't used.)
After this, you unmarshall your input XML and do whatever you want to with the object in memory.
Unmarshaller unmarshaller = context.createUnmarshaller();
EbicsNoPubKeyDigestsRequest ebicsNoPubKeyDigestsRequest =
(EbicsNoPubKeyDigestsRequest) unmarshaller.unmarshal(stream);
Now, if you want to marshall only the header tag which is nested inside the ebicsNoPubKeyDigestsRequest you have to wrap it inside a JAXBElement<...> because the header's type EbicsNoPubKeyDigestsRequest.Header isn't annotated with the #XmlRootElement annotation. You have two (in this case one) way to create this element.
Create an ObjectFactory instance for the corresponding package and use its JAXBElement<T> createT(T t) function. Which wraps its input into a JAXBElement<...>. Unfortunately however, for the header field's type (given your schema files) XJC generates no such method, so you have to do it by hand.
Basically you've almost done it right, but when creating the JAXBElement<...> instead of passing it new QName("header") you have to create a fully-qualifed name, which implies that the namespace is specified too. Passing only the name of the XML tag isn't sufficient, because JAXB won't know this way that this particular header tag is part of the "http://www.ebics.org/H003" namespace. So do it like this:
QName qualifiedName = new QName("http://www.ebics.org/H003", "header");
JAXBElement<EbicsNoPubKeyDigestsRequest.Header> header =
new JAXBElement<EbicsNoPubKeyDigestsRequest.Header>(
qualifiedName, EbicsNoPubKeyDigestsRequest.Header.class, header);
I didn't test if changing only the QName instantiation solves your problem, but maybe it will. However I think it won't and you have to manually manage your prefixes to get a nice and consistent result.