Automate xjc command to generate Java src files from multiple dtd - shell

Am using xjc to generated JAXB based Java source files from individual dtd files...
When trying to use the following command line invocation:
xjc -dtd -d . -p com.myapp.jaxb *.dtd
I received this error message:
parsing a schema...
[ERROR] Too many schema files for this schema language. Compile one file at a time.
unknown location
Failed to parse a schema.
Is there a way (via Unix shell script) to auto generate multiple dtd files?
It would be nice if the Unix shell script can iterate through the entire list of dtds in a dir.
Also, would doing this (automating xjc) negatively effect the ObjectFactory class?
Thanks for taking the time to read this...

I normally concatenate DTDs first in one file prior to compilation. For instance, with the maven-antrun-plugin:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>concatenate-dtds</id>
<phase>generate-sources</phase>
<configuration>
<target>
<concat destfile="src/main/resources/ogc/wms/1.1.0/wms_1_1_0.dtd">
<fileset dir="src/main/resources/ogc/wms/1.1.0" includes="capabilities*.dtd,exception*.dtd"/>
</concat>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<phase>process-sources</phase>
<configuration>
<target>
<delete dir="${basedir}/target/generated-sources/xjc/WMS_1_1_0"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Example from a real project compiling several DTDs:
https://github.com/highsource/ogc-schemas/blob/master/wms/1.1.0/pom.xml#L43-L71

Related

swagger maven plgin executions do not run independant

I use the latest swagger-maven-plugin from the io.swagger.core.v3 to generate my static swagger api documentation.
In my project, I have to separate apis so I want to get a json and yml representation for each api within one package process.
<plugin>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>2.2.6</version>
<configuration>
<outputPath>${basedir}/target/</outputPath>
<outputFormat>JSONANDYAML</outputFormat>
<prettyPrint>true</prettyPrint>
</configuration>
<executions>
<execution>
<id>1</id>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<resourcePackages>
<resourcePackage>de.test.rest</resourcePackage>
</resourcePackages>
<outputFileName>swagger</outputFileName>
<configurationFilePath>${basedir}/src/main/resources/openApiConfig.yml</configurationFilePath>
</configuration>
</execution>
<execution>
<id>2</id>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<resourcePackages>
<resourcePackage>de.test.secondAPI</resourcePackage>
</resourcePackages>
<outputFileName>secondAPI</outputFileName>
<configurationFilePath>${basedir}/src/main/resources/secondOpenApiConfig.yml</configurationFilePath>
</configuration>
</execution>
</executions>
</plugin>
PROBLEM:
the execution creates the expected json and yml files for each execution
swagger.yml
swagger.json
secondAPI.yml
secondAPI.json
The problem is, that the seconAPI files are a copy of the swagger files.
I've read the documentation and I thought that configuration in the plugin root is shared between multiple executions. Configurations within the execution tag are individually used per execution.
Is there a way to run the executions in parallel with individual configuration?
Or is it a problem with the plugin itself?
EDIT:
Each execution works as expected when there is only one execution defined in the executions tag.

exec-maven-plugin equivalent / alternative

In Maven, we can use exec-maven-plugin to execute bash commands in the build.
Which plugin of Central Repository can perform the same task?
I ask it because I have to execute a bash command after another plugin that needs to be executed in the same phase only after exec-maven-plugin, so I can't do it directly inside the exec-maven-plugin.
The bash command that I want to execute in the Maven build is the following:
cat file1 >> file2
Thanks in advance.
I managed to solve my issue with maven-antrun-plugin with the <concat> task:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>final step</id>
<phase>install</phase>
<configuration>
<target>
<concat destfile="${project.build.directory}/${project.artifactId}-${project.version}.sh" binary="yes">
<fileset file="${project.build.directory}/script/self-installer.sh" />
<fileset file="${project.build.directory}/${project.artifactId}-${project.version}.tar.gz" />
</concat>
<chmod file="${project.build.directory}/${project.artifactId}-${project.version}.sh" perm="+x"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
This is the equivalent of the bash cat command.
Keep in mind that if you are concatenating a binary file, you have to set binary="yes", otherwise the Ant task will corrupt the final file.
In any case, this is still not a bash-based solution, it's only a trick that uses Ant routines, so it's not a real equivalent of exec-maven-plugin

Maven : how to order multiple execution of a goal in the same phase in a specfic order

I want my "pre-integration-test" phase to be the following execution of goals, in this specfic order.
PHASE : pre-integration-test
get a spring boot jar (maven-dependency-plugin:copy)
get-a-port (build-helper-maven-plugin:reserve-network-port)
display-port (maven-antrun-plugin:run #1)
start-server (exec-maven-plugin)
wait-for startup (maven-antrun-plugin:run #2)
Is there any way to do this using Maven 3?
The problem that I am facing, is that "maven-antrun-plugin:run" 1 & 2 will always be run one after the other, because they are defined in the same plugin element :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>display-port</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>Displaying value of 'tomcat.http.port' property</echo>
<echo>[tomcat.http.port] ${tomcat.http.port}</echo>
</target>
</configuration>
</execution>
<execution>
<id>wait-for-startup</id>
<phase>pre-integration-test</phase>
<configuration>
<target>
<sleep seconds="10" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Right now, the only way I have found to do this is to duplicate the "maven-antrun-plugin:" plugin element in the pom file.
But this gets me a warning
'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration
For the scope of this question, I am not looking for a work-around, such as changing the plugin for the "display-port" or "wait-for startup", or changing the phase on of the goals.
I just want to understand if what I am trying to do is possible or not.
If multiple executions have the same phase, then the first one to be executed will be the built-in one (e.g. maven-compiler-plugin) whose id is default-something, then the other executions will take place in the order they appear in your pom file.

Check for unresolved properties in Maven Resources

Given the following property in src/main/resources/hello.xml
<test>${resolved.property}</test>
<test>${unresolved.property}</test>
With properties:
resolved.property=test
How do I validate, after going through mvn:resources filtering, if there are any unresolved properties left?
You can use the XML Maven Plugin to validate your XML file after resource filtering has completed.
This plugin can validate XML files against a schema or even just check that they are well formed (which will be sufficient to verify that your XML files do not contain property tokens).
You declare the plugin like so:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
<configuration>
<validationSets>
<validationSet>
<dir>... your xml dir ...</dir>
<includes>
<include>*.xml</include>
</includes>
</validationSet>
</validationSets>
</configuration>
</plugin>
Note: the use of <phase>process-resources</phase> is important here since you want to ensure that validation runs after your resources have been filtered.

Launching a windows batch script using Maven exec plugin blocks the build even though the script uses "start"

I am trying to perform integration tasting of the deployment of my application on the top of a custom container. Since my container is custom, I cannot use Maven Cargo plugin to setup the container.
My container:
Has to be started though a proper bat file, which is in the path of the machine where the tests are run.
Can be manually closed since I have a single maven module containing all my integration tests, even if one day I would like to know how to shut the process down after my tests are completed.
My problem is that I have to run my container in a different process, because it needs to keep running while my tests are performed. Furthermorely, I have an API in my tests that let me wait for the container to be ready (a sort of lookup with timeout).
I have added the following lines to my pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>scripts/start-agent.bat</executable>
</configuration>
</plugin>
This will call a script, which contains only
start call gs-agent.bat
However the mvn exec plugin gets stucked and my tests are not run. According to what is suggested in How do I run a batch file from my Java Application? , I have modified my pom.xml as the following:
<configuration>
<executable>cmd</executable>
<arguments>
<argument>/C</argument>
<argument>start</argument>
<argument>gs-agent.bat</argument>
</arguments>
</configuration>
But this does not seem to solve the issue:
exec plugin is not able to do this, and I found the issue for it, too: http://jira.codehaus.org/browse/MEXEC-87 (link now dead due to codehaus rampdown, can be found from web archive)
In the jira issue linked above, there is a mention and a link of a fork for exec plugin that would have the functionality.
Other than that, I think you'll need to use an antrun-plugin for the time being.
Here's an example taken from working configuration and run with mvn verify. This needs to be in the <plugins>, not <pluginManagement> (exec could reside in pluginmanagement just fine).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<configuration>
<target>
<exec executable="cmd.exe"
spawn="true">
<arg value="/c"/>
<arg value="D:\myfolder\test.bat"/>
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Note that spawn="true" is key here if you don't want the execution to block, like specified in the question. If you do want it to block and see the output immediately, set it to false.
See this question: How do I run a batch file from my Java Application?
Windows Batch Files are not executable. They are scripts that are run by the cmd executable.
More Information
Exec plugin source code reveals that Apache Commons Executor is used to actually execute the command line.
There is a lot of reading you can do here, i.e. in the Apache Commons Executor documentation and their JIRA issues, but the short version is: this isn't a problem with "Maven," it's a problem with the platform-dependent nature of executing an exec() command.
I've tackled this sort of problem before, and the solution I always devise is to deconstruct the .bat script into its actual commands and launch it directly from the exec plugin, rather than calling the script.
The Fallowing Code works for me
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<exec dir="${project.basedir}" executable="Script.bat" failonerror="true">
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Source https://maven.apache.org/guides/mini/guide-using-ant.html
In my case I had trouble with npm and ng.. the underlying problem was exec-maven-plugin was trying to execute the sh scripts (which had no extensions).
Renaming
C:\Users\User\AppData\Roaming\npm\ng to C:\Users\User\AppData\Roaming\npm\ng.sh
and
C:\apps\nodejs\npm to C:\apps\nodejs\npm.sh
solved the problem.
If you want to use exec-maven-plugin here is an example to run a batch script with arguments. E.g. to run something like:
.\test.bat arg1 arg2 arg3
add the following to pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>exec-test</id>
<phase>prepare-package</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>cmd</executable>
<workingDirectory>./</workingDirectory>
<arguments>
<argument>/c</argument>
<argument>start</argument>
<argument>""</argument>
<argument>exec.bat</argument>
<argument>arg1</argument>
<argument>arg2</argument>
<argument>arg3</argument>
</arguments>
</configuration>
</plugin>

Resources