Maven3 profile with custom enforcer rule, is it possible? - maven-3

I wrote and tested a custom enforcer rule to do distribution specific builds on various Linux distributions. It tests well with the mvn enforcer:enforce command, with the provided pom.xml build snippet.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0-beta-1</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-enforcer-rule-redhat6x</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<configuration>
<rules>
<redhat6x implementation="org.example.enforcer.Redhat6x">
<compatible>true</compatible>
</redhat6x>
</rules>
</configuration>
<executions>
<execution>
<id>enforce</id>
</execution>
</executions>
<goals>
<goal>enforce</goal>
</goals>
</plugin>
</plugins>
After racking my brain and doing a lot of experimental testing, I cannot seem to find how to use this custom enforcer rule as a profile activation selector.
<profiles>
<profile>
<id>RedHat6x</id>
<activation>
<!-- Something goes here, but what? This doesn't work -->
<redhat6x implementation="com.cisco.tesdw.enforcer.Redhat6x">
<compatible>true</compatible>
</redhat6x>
</activation>
</profile>
</profiles>
There are some hints that profile activation uses maven-enforcer-rules as detailed in the Introduction to Profiles page under the section "How can I tell which profiles are in effect during a build" section. Namely, every profile activation which has multiple string values (os name, etc) is referred to the corresponding maven enforcer rule. However, it seems that direct inclusion of a custom profile activator isn't obvious in the pom.xml, and adding such would likely require a pom version update.
Maven3 is also extensible in ways that are very flexible, is it possible to hook inclusion of my enforcer rule by the maven extensions mechanism? There is documentation on how to include custom lifecycle participants; but, I fear that profile activation may have already occurred by the time the build starts. Documentation is sparse, but the javadoc indicates that AbstractMavenLifecycleParticipant.afterProjectsRead(MavenSession session) is called "after all MavenProject instances have been created". This leaves some doubt in my mind whether it is called is before of after profile activation. I suspect after, or how would one get a properly configured MavenProject?
Could someone tell me if profile activation customization is even remotely possible?

You just need to move plugin configuration under profile:
<profiles>
<profile>
<id>RedHat6x</id>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0-beta-1</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-enforcer-rule-redhat6x</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<configuration>
<rules>
<redhat6x implementation="org.example.enforcer.Redhat6x">
<compatible>true</compatible>
</redhat6x>
</rules>
</configuration>
<executions>
<execution>
<id>redhat-enforce</id>
</execution>
</executions>
<goals>
<goal>enforce</goal>
</goals>
</plugin>
</plugins>
</profile>
</profiles>

Related

Multi-module maven microservices deploy to Heroku

I have a microservices project with a parent POM and all the other modules with an internal POM.
Locally, if I run mvn clean install -DskipTests everything works.
I want to deploy all the microservices to Heroku, how can i do this?
The project works also for Docker & Kubernetes, is there a way to integrate also Docker in Heroku?
So it will be beautiful if I can deploy all the microservices as 1 project in Heroku, with every microservices as a Docker image.
Thank you in advance!
This is an example of my project:
Parent POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.petcare</groupId>
<artifactId>website-petcare-backend</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent-pom</name>
<modules>
<module>apiGateway</module>
<module>reservationService</module>
<module>userService</module>
<module>eurekaServer</module>
<module>mapService</module>
<module>authService</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Build
You can build all images for the sub-modules using the docker-maven-plugin.
Each sub-module must have its own Dockerfile, then in the parent POM add:
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.38.1</version>
<executions>
<execution>
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>build</goal>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
When running mvn clean package docker:build all projects are built and Dockerized
Deploy
Deploying all images (each image into its own web Dyno) is a little bit more complicated. You have few options:
Script from the command line: typically you can push the image with the following commands
heroku container:push web -a appname
heroku container:release web a appname
You could build a script that performs those steps for each and (very important) performs both the heroku login and heroku:container login using the credentials
Using heroku.yml where you can define at once all the containers to be deployed. It is a good approach but you need to git push your changes (see here)
Use CI/CD application like Github Actions. In this case your workflow compiles, tests, builds and pushes the application.
This is my preferred approach: you can decide when to build/deploy (on master push? manually?), you save the Heroku credentials as secrets, you can automate the release pipeline.
You can read more here
You can also try the Heroku Docker Maven plugin if you like to control all services using Maven

liquibase maven plugin disable checksum

I'm using liquibase with maven-3. The first run works as expected. Consecutive runs though (even if the sql files contain changes) fail, as they are viewed as equivalent from liquibase and ignored (checksum).
All the sql actions in my sql scripts have taken into account the previous runs, so I don't want this behaviour. With this setup that you see below, how can I force liquibase to always execute my scripts, no matter the changes?
As you can see below I've already tried setting clearCheckSums as a goal and indeed it clears the hash values, but still no luck (thus commented out).
This is the profile I've created
<profile>
<id>liquibase-executions</id>
<build>
<defaultGoal>process-resources</defaultGoal>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.2</version>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>update-schema</id>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
<!--<goal>clearCheckSums</goal>-->
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://${db.url}</url>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
<changeLogFile>${basedir}/src/main/resources/liquibase.sql</changeLogFile>
</configuration>
</execution>
<execution>
<id>update-data</id>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
<!--<goal>clearCheckSums</goal>-->
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://${db.url}</url>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
<changeLogFile>${basedir}/src/main/resources/liquibase-populate.sql</changeLogFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
And this is how I execute it
mvn process-resources -Pliquibase-executions -Ddb.url=POSTGRES_IP:5432/POSTGRES_DB -Dliquibase.username=POSTGRES_USERNAME
The Liquibase Maven plugin expects a changelog file, no plain .sql file. This file should contain your changeSets that you want Liquibase to execute. These changeSets can be instructed to be run every time you run Liquibase (by default they're only executed once). So there's no need to tamper with the checksum. For example your changelog file could look something like this:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="your-id" author="msp" runAlways="true">
...
</changeSet>
</databaseChangeLog>
The important part to achieve your intended behaviour is to set the runAlways="true" attribute in your liquibase changeset.

Spring Boot Maven Plugin

I have two classes with main method and one loads the security configuration and the other does not. In order to create two artifacts - secure and non secure jars, I am doing something like the following :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>1</id>
<configuration>
<mainClass>a.b.c.Secured</mainClass>
<finalName>secured</finalName>
<classifier>secured</classifier>
</configuration>
</execution>
<execution>
<id>2</id>
<configuration>
<mainClass>a.b.c.NonSecured</mainClass>
<finalName>non-secured</finalName>
<classifier>nonSecured</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
And I am seeing the exception -
java.lang.IllegalStateException: Unable to find a single main class from the following candidates.
Can you please let me know, if there is some thing wrong with the above configuration? I may be able to use maven profiles to create different artifacts. However, I wanted to understand the problem with the above configuration. Any help will be greatly appreciated.
I think both those configurations are active at the same time (otherwise how do you tell maven which one to use?). You could put them both in Maven profiles.

How to override Maven 3.0 parent profile properties from child pom?

How to override Maven 3.0 parent profile properties from child pom?
I want to be override profile properties from a parent pom. I've used help:effective-pom -Pjmeter and can see that the child properties are not being picked up and tried many various permutations all without success. I expect the parents properties to be overridden by the child properties.
Parent pom profile:
<profile>
<id>jmeter</id>
<properties combine.self="override">
<maven.jmeter.phase>verify</maven.jmeter.phase>
<maven.jmeter.goal>jmeter</maven.jmeter.goal>
<!-- We use the ${basedir} to avoid NullPointer errors when src/test/jmeter doesn't exist -->
<!-- when running jmeter test the default to set in the child pom is ${basedir}/src/test/jmeter -->
<maven.jmeter.testFilesDirectory>${basedir}</maven.jmeter.testFilesDirectory>
<maven.jmeter.jMeterTestFile>**/*.jmx</maven.jmeter.jMeterTestFile>
<maven.jmeter.excludeJmeterTestFile>NOT_NULL</maven.jmeter.excludeJmeterTestFile>
<maven.jmeter.testResultsTimestamp>false</maven.jmeter.testResultsTimestamp>
<maven.jmeter.server>localhost</maven.jmeter.server>
<maven.jmeter.port>8080</maven.jmeter.port>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>${jmeter.version}</version>
<executions>
<execution>
<id>jmeter-tests</id>
<phase>${maven.jmeter.phase}</phase>
<goals>
<goal>${maven.jmeter.goal}</goal>
</goals>
<configuration>
<testFilesDirectory>${maven.jmeter.testFilesDirectory}</testFilesDirectory>
<testFilesIncluded>
<jMeterTestFile>${maven.jmeter.jMeterTestFile}</jMeterTestFile>
</testFilesIncluded>
<testFilesExcluded>
<excludeJmeterTestFile>${maven.jmeter.excludeJmeterTestFile}</excludeJmeterTestFile>
</testFilesExcluded>
<testResultsTimestamp>${maven.jmeter.testResultsTimestamp}</testResultsTimestamp>
<propertiesUser>
<!-- server and port must be defined (and used) in the JMeter jmx file as User Defined Variables
${__P(server,localhost)}
${__P(port,80)}
See http://jmeter.apache.org/usermanual/component_reference.html#User_Defined_Variables
http://jmeter.apache.org/usermanual/test_plan.html#using_variables
http://jmeter.apache.org/usermanual/functions.html#__P
http://jmeter.apache.org/usermanual/best-practices.html#parameterising_tests
-->
<server>${maven.jmeter.server}</server>
<port>${maven.jmeter.port}</port>
</propertiesUser>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
and then in the child pom:
<profile>
<id>jmeter</id>
<activation><activeByDefault>false</activeByDefault></activation>
<properties>
<maven.jmeter.testFilesDirectory>${project.basedir}/src/test/jmeter</maven.jmeter.testFilesDirectory>
<!-- csv based JMeter tests result in one graph in Jenkins, we want a graph per test -->
<maven.jmeter.excludeJmeterTestFile>**/KRAD.jmx</maven.jmeter.excludeJmeterTestFile>
</properties>
</profile>
I'm not sure properties are overridden that way. Either way, the plugin will not run as you have it, since you only define <pluginManagement> and no straight direct <plugins> child under <build>. If you don't want your plugin to run in the parent, just define the <plugins> tags in the children where you do want this running as such:
<profile>
<id>jmeter</id>
<activation><activeByDefault>false</activeByDefault></activation>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<configuration>
<testFilesDirectory>${maven.jmeter.jMeterTestFile}</testFilesDirectory>
<!-- csv based JMeter tests result in one graph in Jenkins, we want a graph per test -->
<testFilesExcluded>
<excludeJmeterTestFile>${maven.jmeter.excludeJmeterTestFile}</excludeJmeterTestFile>
</testFilesExcluded>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Hope this helps.

Maven for building SOA services and clients?

I changed the title to generalize this question which really isn't specific to Axis2. I eventually gave up on Axis2 altogether and switched to Metro/JAX-WS but am now seriously considering giving up on both and switching to OpenSAML. The real question I'm struggling to get answered here is, how to build complex standards-based SOA services that actually work.
The original phrasing was: Could someone paste in a working example of maven pom to invoke Axis2 java2wsdl with defaults I can live with? Here's a command line incantation that behaves sort of OK.
-o target/generated-sources/java2wsdl \
-l "http://localhost:9763/services/PolicyService" \
-tn urn:sesgg:sc:security:1.0.spec.PolicyService \
-tp ps \
-stn urn:oasis:names:tc:SAML:2.0:protocol \
-stp samlp \
-of PolicyService.wsdl \
-sn PolicyService \
-cp "../../Schema/target/Schema-1.0-SNAPSHOT.jar target/PolicyService-1.0-SNAPSHOT.jar" \
-cn com.technica.pbac.ps.PolicyService \
Everything I do winds up with really squirrely results; e.g. weird reversed namespaces (http://xmldsig._09._2000.w3.org/xsd for example). Could you explain why this is and how to stop it?
There seems to be a lot java2wsdl's out there that expect entirely different arguments, with little consistency between command line and maven pom.
No responses so I'll post current results of my own experiments to help others with
similar problems. Can't guarantee this is correct until testing is finished but at least now I'm getting results I can bear looking at in Eclipse:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.5</version>
<configuration>
<schemaExcludes>
<exclude>*saml*.xsd</exclude>
</schemaExcludes>
<strict>true</strict>
<extension>true</extension>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-java2wsdl-maven-plugin</artifactId>
<version>1.5.4</version>
<executions>
<execution>
<goals>
<goal>java2wsdl</goal>
</goals>
</execution>
</executions>
<configuration>
<id>Generate WSDL based on PolicyService Interface</id>
<serviceName>PolicyService</serviceName>
<className>com.technica.pbac.ps.PolicyServiceImpl</className>
<targetNamespace>http://sesgg/sc/security/1.0/spec/PolicyService</targetNamespace>
<targetNamespacePrefix>sesgg</targetNamespacePrefix>
<schemaTargetNamespace>http://sesgg/sc/security/1.0/spec/PolicyService</schemaTargetNamespace>
<schemaTargetNamespacePrefix>sesgg</schemaTargetNamespacePrefix>
<elementFormDefault>qualified</elementFormDefault>
<extension>false</extension>
<package2Namespace>
<property>
<name>urn:sesgg:sc:security:1.0:spec:PolicyService</name>
<value>http://sesgg/sc/security/1.0/spec/PolicyService</value>
</property>
<property>
<name>com.technica.pbac.ps</name>
<value>http://com.technica.pbac.ps</value>
</property>
<property>
<name>oasis.names.tc.saml._2_0.protocol.xsd</name>
<value>http://oasis/names/tc/saml/2.0/protocol</value>
</property>
<property>
<name>oasis.names.tc.saml._2_0.protocol</name>
<value>http://oasis/names/tc/saml/2.0/protocol</value>
</property>
</package2Namespace>
<episodes>
<episode>
<groupId>Technica-PBAC</groupId>
<artifactId>Schema-1.0-SNAPSHOT.jar</artifactId>
</episode>
</episodes>
<outputFileName>target/generated-sources/java2wsdl/PolicyService.wsdl</outputFileName>
<filename>target/generated-sources/java2wsdl/services.xml</filename>
<locationUri>http://localhost:9763/services/PolicyService</locationUri>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.5.4</version>
<executions>
<execution>
<goals>
<goal>wsdl2code</goal>
</goals>
<configuration>
<wsdlFile>target/generated-sources/java2wsdl/PolicyService.wsdl</wsdlFile>
<packageName>com.technica.pbac.ps</packageName>
<outputDirectory>target/generated-sources/wsdl2java</outputDirectory>
<unwrap>true</unwrap>
<allPorts>true</allPorts>
<databindingName>adb</databindingName>
<generateServerSide>true</generateServerSide>
<generateAllClasses>true</generateAllClasses>
<generateServicesXml>true</generateServicesXml>
<generateTestcase>true</generateTestcase>
<overWrite>true</overWrite>
<serviceName>PolicyService</serviceName>
<syncMode>sync</syncMode>
<backwardCompatible>false</backwardCompatible>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-java2wsdl-maven-plugin</artifactId>
<version>1.5.4</version>
</plugin>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.5.4</version>
</plugin>
</plugins>
</pluginManagement>
</build>
One caution: I really doubt its right to be running jaxb, java2wsdl, wsdl2java and compile phases in a single pom. Currently java2wsdl runs after wsdl2java this way which obvously isn't right. This pom is doubly suspicious since java2wsdl needs a compiled jar to run, and seems to be using the one left over from previous runs. Its a bear to get working again after mvn clean. I'll probably wind up splitting it into several poms and will adjust this answer when I do.
I promised to extend this answer with something approximately "right". Here is progress to date, which I'm still not absolutely sure is 100% correct. More about that later.
This is all based on the stack of schema Oasis publishes to define the XACML and SAML-P for XACML standards. The XSD's have been gathered into a Commons-Schema module (not shown), tweaked to fix several Oasis errors, and compiled to Java classes with JAX-B. These classes are the foundation for the services described below. The schema.episode.path and schema.catalog.path properties point to files in this module.
I split each service (PolicyService in this case) into two maven modules. PolicyService-Svc is the service and its pom looks like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<id>Generate WSDL</id>
<phase>generate-resources</phase>
<goals>
<goal>wsgen</goal>
</goals>
<configuration>
<sei>com.technica.pbac.ps.PolicyService</sei>
<genWsdl>true</genWsdl>
<keep>true</keep>
<verbose>true</verbose>
<extension>true</extension>
<catalog>${schema.catalog.path}</catalog>
<xjcArg>-episode</xjcArg>
<xjcArg>${schema.episode.path}</xjcArg>
<xjcArg>-catalog</xjcArg>
<xjcArg>${schema.catalog.path}</xjcArg>
</configuration>
</execution>
</executions>
</plugin>
PolicyService-Proxy is generic proxy code that any client or service can use to invoke that service (more about problems with this below). Its pom looks like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<!-- <phase>generate-sources</phase> -->
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlFiles>
<wsdlFile>localhost_8080/PolicyService-Svc/PolicyService.wsdl</wsdlFile>
</wsdlFiles>
<wsdlLocation>http://localhost:8080/PolicyService-Svc/PolicyService?WSDL</wsdlLocation>
<sourceDestDir>${project.build.directory}/generated-sources/jaxws</sourceDestDir>
<genWsdl>true</genWsdl>
<verbose>true</verbose>
<extension>true</extension>
<catalog>${schema.catalog.path}</catalog>
<xjcArg>-episode</xjcArg>
<xjcArg>${schema.episode.path}</xjcArg>
</configuration>
</execution>
</executions>
</plugin>
Now for the problems, which I'd really appreciate advice on. Even though Commons-Schema provides compiled java classes for all schema, wsgen insists on producing a wsdl with newly-generated xsds, which are slightly different and slightly incorrect in various ways.
As one example of incorrect and different, SAML defines an Extensions element that conflicts with the same name in another schema. So I repaired it in the base Commons-Schema like this:
<element name="Extensions" type="samlp:ExtensionsType">
<annotation>
<appinfo>
<jxb:class name="Extensions-SAML"/>
</appinfo>
</annotation>
</element>
But wsgen/wsimport omits this correction so the conflict turns up again. Infuriating and absolutely fatal to the build.
Another is omitting required includes so eclipse validation reports them as errors until hand-corrected. My workaround is to periodically copy the generated wsdl and xsds from the target folder to src/main/webapp/WEB-Inf/wsdl, repair them by hand, and tweak the poms to use this folder instead of the generated one inside target. This works for invoking services from non-service clients. I copy the same wsdls and xsds to a similar client folder and ensure that the pom references these, not the ones jaxws generates in that module.
The problem I can't solve occurs when any service needs to invoke another service via its proxy. The calling service's proxy jar (with its slightly different versions of important foundation classes) is now mixed in with the calling service jars (based on Commons-Schema's JAXB-generated classes), which causes no end of trouble.
Can someone please advise? Thanks!
The ultimate answer to this question was indeed to give up on trying to fix busted schemas and tools and switch to OpenSAML, which has already done that. This worked fine for the XACML 2.0 compiler and web services based on it. But it fell flat for the XACML 3.0 compilers because OpenSAML doesn't support XACML 3.0 and has no plans to do so, so I had to handle that myself. But with experience with XACML 2.0 to build on, I eventually got both working. This project was far more painful than it had to be and "powerful" tools just made it harder.

Resources