I'm trying to revive a legacy project for my client. The project is pretty old and it uses the jaxb2-maven-plugin to generate some java classes from an xsd schema file.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/resources/custom-api.xsd</source>
</sources>
<packageName>com.client</packageName>
<catalog>src/main/resources/catalog.cat</catalog>
</configuration>
</plugin>
The problem is the company doesn't allow any internet access - hence when I generate the code I get errors such as java.net.UnknownHostException saying that it cannot find www.springframework.org.
So I understand that the solution for this problem is to provide the xsd files locally - which I did, extracting them in a folder named import and I created also a catalog.cat file to rewrite the access to those xsd files to the import folder.
The catalog.cat file looks like this:
REWRITE_SYSTEM "http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" "import/spring-beans-3.1.xsd"
REWRITE_SYSTEM "http://www.mulesoft.org/schema/mule/core/3.4/mule.xsd" "import/mule.xsd"
REWRITE_SYSTEM "http://www.mulesoft.org/schema/mule/schemadoc/3.4/mule-schemadoc.xsd" "import/mule-schemadoc.xsd"
REWRITE_SYSTEM "http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd" "import/mule-jms.xsd"
REWRITE_SYSTEM "http://www.springframework.org/schema/context/spring-context-3.1.xsd" "import/spring-context-3.1.xsd"
REWRITE_SYSTEM "http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" "import/spring-tool-3.1.xsd"
Unfortunately I get some conflicts in spring-beans.xsd:
com.sun.istack.SAXParseException2publicId: http://www.springframework.org/schema/beans; systemId: http://www.springframework.org/schema/beans/spring-beans-3.1.xsd; lineNumber: 566; columnNumber: 30; Property "Ref" is already defined. Use <jaxb:property> to resolve this conflict.
at com.sun.tools.xjc.ErrorReceiver.error(ErrorReceiver.java:56)
I suspect that this happens because the xsd is loaded multiple times - probably being referenced by other xsd files. The usual way to get rid of such conflicts is to use a binding file, but I don't think this is the right thing to do considering that this is a third party xsd file.
An example of a sample project has been provided here: https://github.com/scutaru/sample-xjc
Anybody knows how I can get rid of these conflicts ?
The EU VIES VAT validation from WSDL is not working when running via java code. But the same is working from some soap API testing tools.
Eg, https://wsdlbrowser.com/soapclient?wsdl_url=https%3A%2F%2Fec.europa.eu%2Ftaxation_customs%2Fvies%2FcheckVatService.wsdl and https://app.boomerangapi.com/?ext
Even its not working when I trid to get source code from wsimport. (C:\Program Files\Java\jdk1.8.0_151\bin>wsimport -keep -verbose http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl)
Error is “The element type "BR" must be terminated by the matching end-tag "".” The same error is coming when trying to access SOAP service via java code.
Any suggestions on how to use this EU wsdl for validating VAT nos?
Solved this using 'JAX-WS' Maven plugin to parse a WSDL file to generate java classes.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<execution>
<id>wsimportb-from-jdk</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlUrls>
<wsdlUrl>
https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
</wsdlUrl>
</wsdlUrls>
<keep>true</keep>
<packageName>com.vies</packageName>
<sourceDestDir>target/generatedclasses</sourceDestDir>
</configuration>
</execution>
Then export your com.vies custom package under maven <Export-Package>
Change protocol http:// to https:// in the WSDL URL
I am using the Java Jersey framework(with Maven), and use IntelliJ as my IDE. I have encountered this runtime exception that ONLY happens when I try to run the code from the command line (using maven to compile and then java -jar ) but NOT when running within IntelliJ, which is strange.
I have some Java code that will try to make an HTTP GET on some remote URL and try to read the returned JSON into some Lombok POJO :
String targetUrl = "some valid URL";
WebTarget webTarget = client.target(targetUrl);
Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).get();
ParseResponse parseResponse = response.readEntity(ParseResponse.class);
I am not sure why, but when it hits that last line that does the "readEntity()" method, I will get the error below:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/json; charset=utf-8
This is strange, because I definitely have the jersey-media-json-jackson dependency specified in my pom.xml :
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.23</version>
</dependency>
and this is my POJO class that I was trying to readEntity() into :
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public class ParseResponse {
#JsonProperty("id")
private Integer id;
...Other params...
}
And like I mentioned before, it is strange that this only happens when I try to run on the command line like this but there is no error when running in IntelliJ:
mvn clean package
java -jar target/NameOfJar.jar
Did I miss something obvious here? I have looked at other people with similar issues like this online but haven't found a solution.
Thanks
IS
If you look inside the jersey-media-json-jackson jar you should see a file
META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
The contents of this file should be a single fully qualified name of a class that implements the name of the file, namely
org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable
This file is used by Jersey auto-discoverable mechanism to automatically register features without us having to explicitly register them. Briefly, how it works, is that all Jersey modules/jars that have components that should be automatically registered, should have the above named file located in the jar, with the contents being the name(s) of the auto-discoverable component. Jersey will then use the Service Loader pattern to load the classes named in the file, and register them.
The problem this causes when creating uber jars is that you can only have one copy of a file, you can't have duplicates. So what if we have multiple jars with the above file? Well only one of those files will be included in the uber jar. Which one? Who knows, but there is only one lucky winner. So for the rest of the jars, their auto-discover mechanism never kicks in. This is the case with your Jackson feature, where the auto-discoverable registers the JacksonFeature. You can try to explicitly register with your application, and you should see that it now works.
But what about other jars/modules that may have this file? It's for this reason that when creating uber jars, you should use the maven-shade-plugin. What this plugin allows you to do, is combine the contents of the files so that all the discoverables get included into that one single file. Below is an example usage
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.YourApp</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
This example was actually taken from Dropwizard's Getting Started. You can check it out for further explanation. The main part of concern the ServicesResorceTransformer, which is what concatenates the services files.
I want dynamically exchange the webserive targetnamescpace (host) in the cade generated by Apache CXF.
Why? Each customer has its own wsdl file.
The current situation is that there is one project, that depends on wsdl X that is hosted on serverX. That means for each Customer an extra build with he specific wsdl URL.
The wsdl files are always identically, just the server changes.
A fat jar (jar-with-dependencies) will be build and uploaded to our nexus server.
We use Java 7 and Maven 3 to build our projects.
The problem is when deploying to nexus you cannot change the change the name of the artifact that gets deployed. application-1.0-CUSTOMER.jar would be a nice pattern but i didn't found a way to solve that and also the whole process dosen't seem very clean.
The webservice-.java files gets generated by the cxf-codegen-plugin plugin. I am using this configuration:
<!-- CXF wsdl2Java Generation -->
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf/</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>
http://trunk. ....
</wsdl>
<serviceName>ServiceName</serviceName>
<extraargs>
<extraarg>-impl</extraarg>
<extraarg>-verbose</extraarg>
<!-- override the namespace to have always identical package names -->
<extraarg>-p</extraarg>
<extraarg>de.packagename.wsdl</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Here one of the generated java files:
/**
* This class was generated by Apache CXF 2.7.0
* 2013-11-13T14:35:21.046+01:00
* Generated source version: 2.7.0
*
*/
#WebService(targetNamespace = "http://trunk...", name = "SomeName")
#XmlSeeAlso({ObjectFactory.class})
public interface SomeName {
...
}
My idea was to cut out the whole webservice-client implementation out of that application and put it in another project (one project one customer) -- but how to call the webservice from the original project? Currently one Interface is used by the original project as well as one model class.
I know that there is a hack around the deployment problem by using a artifact version with a variable, but it is highly discouraged, at least in maven 3.
I resolved it.
Its similar to this one: How to create a CXF webservice client with dynamic endpoint? but only after a half day debugging i found my solution.
final QName qname = new QName(Settings.MAIN_SCAN_SERVICE_SOAP_URL.get().toString(), "PortName");
final String wsdlUrl = Settings.MAIN_SCAN_SERVICE_WSDL_URL.get().toString();
final JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setAddress(Settings.MAIN_SCAN_SERVICE_SOAP_URL.get().toString());
jaxWsProxyFactoryBean.setEndpointName(qname);
jaxWsProxyFactoryBean.setServiceName(new QName(wsdlUrl, "PortName"));
jaxWsProxyFactoryBean.setWsdlLocation(wsdlUrl);
jaxWsProxyFactoryBean.setServiceClass(PortImpl.class);
this.portImpl = (PortImpl) jaxWsProxyFactoryBean.create();
Our project uses XJC to generate Java classes from an XSD. I'm using JAVA EE 6.
When all the XSDs we have are re-generated, the generated classes include this comment at the top of the file:
// Generated on: 2011.02.23 at 02:17:06 PM GMT
Is it possible to suppress this comment? The reason is that we use SVN for version control, and every time we regenerate our classes, every single file shows as being changed in SVN, even though the only thing that differs is this comment. So I'd like to remove the comment altogether if possible.
There is a -no-header directive, but I don't want to remove the entire header, so that future generations know that it's a file generated from a tool, and that modifications will be overwritten. I only want to remove the timestamp. (Or alternatively, I'd remove the inbuilt header and then insert my own header somehow.)
I am using this Maven plugin which replaces the // Generated on: 2011.02.23 at 02:17:06 PM GMT line:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.3.8</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>src/main/java/jaxb/*.java</include>
</includes>
<token>^// Generated on.*$</token>
<value>// Generated on: [TEXT REMOVED by maven-replacer-plugin]</value>
<regexFlags>
<regexFlag>MULTILINE</regexFlag>
</regexFlags>
</configuration>
</plugin>
I'm late to the party, but since version 2.0 of the jaxb2-maven-plugin, there's a noGeneratedHeaderComments configuration option. (see the JAXB-2 Maven Plugin Docs)
You can use it like this:
...
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<target>2.1</target>
<sources>
<source>FirstXSD.xsd</source>
<source>SecondXSD.xsd</source>
</sources>
<xjbSources>
<xjbSource>OptionalBindings.xjb</xjbSource>
</xjbSources>
<noGeneratedHeaderComments>true</noGeneratedHeaderComments>
</configuration>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>${jaxb.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
...
So no need for another plugin or script to run.
If you want to keep a disclaimer, you can use one of the techniques already mentioned to inject it where wanted.
If you use ant, the following snippet may be useful for replacing the comments:
<replaceregexp
match="^// Generated on:.*$"
replace="// Generated on: [date removed]"
byline="true">
<fileset dir="src">
<include name="**/*.java"/>
</fileset>
</replaceregexp>
I know this is 2 years after the fact, but because the classes are generated they aren't necessarily needed in SVN. What needs to be in SVN is the schema or whatever file you use for source to generate the classes. As long as you have the source and the tools to generate the classes, the classes in SVN are redundant and as you saw, problematic in SVN or any SCCS. So put the schema file in SVN and avoid the issue altogether.
If it's not possible using an option you can post-process the generated files yourself.
For a very specific use-case we had to do it that way on our project...
We use Maven and we execute a specific script after the Java classes have been generated and before we compile and package them to a distriuable JAR.
To build on cata's answer (upvoted) the maven-replacer-plugin is the way to go. I've come up with the following that strips out the entire comment (not just the timestamp) which you can replace with your file comment (license etc.).
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- assumes your xjc is putting source code here -->
<includes>
<include>src/main/java/**/*.java</include>
</includes>
<regex>true</regex>
<regexFlags>
<regexFlag>MULTILINE</regexFlag>
</regexFlags>
<replacements>
<replacement>
<token>(^//.*\u000a|^\u000a)*^package</token>
<value>// your new comment
package</value>
</replacement>
</replacements>
</configuration>
</plugin>
The one gotcha to watch out for is that the <value> element treats the text literally. So if you want a line break in your replacement text you need to put a line break in your pom.xml file (as I've demonstrated above).
What you should you :
Generate your classes in target :
${project.build.directory}/generated-sources
If you add target to ignore list (svn), that's all.
I also want to have text header with warning about classes was auto-generated and should not be modified manually, but because I place such files into git I do not want there always changed date of generation.
That header generated in com.sun.tools.xjc.Options#getPrologComment method. So essentially it call:
return Messages.format(
Messages.FILE_PROLOG_COMMENT,
dateFormat.format(new Date()));
Messages.FILE_PROLOG_COMMENT defined as Driver.FilePrologComment. With futher debugging I found it use standard Java localization bundles.
So, to change header format we just may provide our properties override for their values from MessageBundle.properties.
We can do it in two way:
Just copy that file (from repo by link, or just from jar of appropriate version what you are using) into src/main/resources/com/sun/tools/xjc/MessageBundle.properties in your project and change key Driver.FilePrologComment as you wish.
But first case have some drawbacks - first you copy-paste many code which you do not change, second you should update it when you update XJC dependency. So better I recommend place it as src/main/resources/com/sun/tools/xjc/MessageBundle_en.properties (note _en suffix in filename) file and place there only properties you really want to change. Something like:
# We want header, but do NOT willing there `Generated on: {0}` part because want commit them into git!
Driver.FilePrologComment = \
This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.4.0-b180830.0438 \n\
See https://javaee.github.io/jaxb-v2/ \n\
Any modifications to this file will be lost upon recompilation of the source schema. \n
Ensure that file in compiler classpath, especially if you call it from some plugins.
That is common mechanism for translation. See related answer: JAXB english comments in generated file
If you are using maven-jaxb2-plugin there is an tag noFileHeader set it to true. It will prevent jaxb to generate the header that includes that date line on it.
<noFileHeader>true</noFileHeader>