Spring Boot Maven Plugin - maven-3

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.

Related

Maven - Shade Plugin doesn't work when creating Manifests

I have tried shading my jar using a custom manifest file and also manifest entries. In both cases, it's not even accepting any manifest file.
I have looked into Apache Maven docs for Shade plugin and it's not working as per the docs.
Here is my Shade Config:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>kafkapub.main.app.MainApp</mainClass>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</transformer>
</transformers>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>launcher</shadedClassifierName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Has anyone seen similar issues ?
I think I sorted the issue.
Basically it created the -shaded artifacts. And since there were three jars:
original-*.jar
*.jar
*-shaded.jar
It was quite confusing. But I can see everything in the Shaded jar now thanks.

Does -nexclude work when using JiBX as the CXF databining?

I am trying to get CXF (2.7.7) to use JiBX (1.2.5) for databinding. The documentation is a bit sketchy, but there have been reports of success with it. One problem is that CXF does not pass configuration to the JiBX code generator, so if you need to do something that requires customization, such as mapping Joda DateTime to XML Schema date, you need to be able to tell CXF to ignore specific namespaces and then handle those with a separate call to JiBX.
The examples I have seen use the CXF -nexclude flag for this purpose, as in
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generateSources</id>
<phase>generate-sources</phase>
<goals>
<goal>wsdl2java</goal>
</goals>
<configuration>
<sourceRoot>${generated-sources.dir}/cxf</sourceRoot>
<wsdlRoot>${wsdl.dir}</wsdlRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${wsdl.dir}/GetCounters.wsdl</wsdl>
<dataBinding>jibx</dataBinding>
<extraargs>
<extraarg>-nexclude</extraarg>
<extraarg>http://www.example.com/counters/</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
</execution>
</executions>
</plugin>
I have tried both inline and imported versions of the namespace but the -nexclude flag does not appear to work with JiBX. One option might be to let JiBX do the whole WSDL without invoking the CXF plugin, but apparently this creates problems in the generated service code. An ugly workaround might be to let JiBX regenerate the code for just the classes in this namespace, overwriting the code created by CXF.
Can the -nexclude flag be made to work?
I was having a similar problem while using jaxb. This worked for me:
move the extraargs out of the wsdlOption section and into the defaultOptions section.
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cfx.codegen.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<defaultOptions>
<extraargs>
<extraarg>-nexclude</extraarg>
<extraarg>http://domain.company.org/v1/schema1</extraarg>
<extraarg>-nexclude</extraarg>
<extraarg>http://domain.company.org/v1/schema2</extraarg>
</extraargs>
</defaultOptions>
<wsdlOptions>
<wsdlOption>
<wsdlArtifact>
<groupId>org.company</groupId>
<artifactId>application-contract</artifactId>
<version>${contract.version}</version>
<type>wsdl</type>
</wsdlArtifact>
</wsdlOption>
</wsdlOptions>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>

Maven3 profile with custom enforcer rule, is it possible?

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>

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.

Installing a wsdl file into a Maven repository

I'm trying to install a wsdl file into a remote Maven repository so I can reference it in a CXF project as per this blog post.
I'm sure it could be done manually, but I want an actual maven project so I can make use of the release plugin for tagging etc.
Has anybody got experience with this?
You can use the build helper maven plugin to do this. Here is an indicative code snippet
<build>
...
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${wsdlLocation}/project.wsdl</file>
<type>wsdl</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build.

Resources