Maven: how to invoke a plugin with execution specific config - maven

I have written a plugin and want to treat the goal vrs (check versions) differently,
depending on execution/command line.
In my code I added
#Parameter(name = "versionsWarnOnly", defaultValue = "true")
private boolean versionsWarnOnly;
public boolean getVersionsWarnOnly() {
System.out.println("invoked get");
return this.versionsWarnOnly;
}
public void setVersionsWarnOnly(boolean versionsWarnOnly) {
System.out.println("invoked set");
this.versionsWarnOnly = versionsWarnOnly;
}
I would expect, that without specifying versionsWarnOnly in the configuration in the pom, i just get the defaultValue specified.
The problem is, that does not happen, it is always false in that case.
If i configure in the configuration
of the plugin in the pom
<versionsWarnOnly>true</versionsWarnOnly>
Then this is done (well some success) if I build the phase mvn validate.
It is even true if I invoke the goal from the command line by goal mvn latex:vrs.
But if i specify that in an execution that like,
<execution>
<id>validate_converters</id>
<phase>validate</phase>
<configuration>
<versionsWarnOnly>true</versionsWarnOnly>
</configuration>
<goals>
<goal>vrs</goal>
</goals>
</execution>
again it has no effect.
I have no idea what i do wrong
or what kind of information you need to help me.

The problem is resolved and the question could be deleted altogether.
The problem was that I put almost all of the config into a class Settings.
On the other hand, I added the new parameter outside and so it had no effect.
Thats all.
Now all works fine.

Related

Maven Enforcer: How to access maven properties from beanshell rule

I successfully created a evaluateBeanshell rule with the maven-enforcer-plugin that scans files in the workspace for common mistakes.
With a hardcoded path the rule works fine. When I want to use the ${project.basedir} variable from the surrounding pom, the script breaks on my Windows machine.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>${maven-enforcer-plugin.version}</version>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<inherited>true</inherited>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<evaluateBeanshell>
<condition>
import scanner.MyScanner;
scanner = new MyScanner();
//hack to read root dir
//project.basedir crashes beanshell with its backslashes
rootPath = new File("");
root = new File(rootPath.getAbsolutePath());
print("Scanning in: " + root);
print("${project.artifactId}"); // works fine
print("${project.basedir}"); // breaks the code
scanner.loopThroughProjects(root);
return everythingIsFine;
</condition>
</evaluateBeanshell>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
In the debug output the line:
print("${project.basedir}");
was replaced by:
print("D:\code\my-maven-project");
Is there another maven property with sanitized slashes or is there another way to access ${project.basedir}?
The hack outlined in the code example kind of works, but I don't like hacks that force me to leave comments.
You could try ${project.baseUri}.
See https://maven.apache.org/ref/3.8.5/maven-model-builder/#Model_Interpolation
On my Windows 10 machine with Java 8 and Maven 3 the following test properties in pom.xml:
<test>${project.baseUri}</test>
<test2>${project.basedir}</test2>
become the following in the 'effective-pom' (via Intellij IDEA maven plugin)
<test>file:/D:/test/path/</test>
<test2>D:\test\path</test2>
This is just as a proof of concept to show the path separators change, and become valid as a Java String.
You could then transform the URI to a file for your needs in the beanshell script as follows:
uri = java.net.URI.create("${project.baseUri}");
root = new java.io.File(uri);
Via https://docs.oracle.com/javase/8/docs/api/java/io/File.html#File-java.net.URI-

Spring Boot: Thymeleaf not resolving fragments after packaging

im using fragments like this:
#RequestMapping(value="/fragment/nodeListWithStatus", method= RequestMethod.GET)
public String nodeListWithStatus(Model model) {
// status der nodes
model.addAttribute("nodeList", nodeService.getNodeListWithOnlineStatus());
return "/fragments :: nodeList";
}
The templates are in /src/main/resources/templates. This works fine when starting the application from IntelliJ.
As soon as i create an .jar and start it, above code no longer works. Error:
[2014-10-21 20:37:09.191] log4j - 7941 ERROR [http-nio-666-exec-2] --- TemplateEngine: [THYMELEAF][http-nio-666-exec-2] Exception processing template "/fragments": Error resolving template "/fragments", template might not exist or might not be accessible by any of the configured Template Resolvers
When i open the .jar with winrar, i see /templates/fragments.html - so it seems to be there.
My pom.xml has this part for building the jar (Maven clean, install) :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>de.filth.Application</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Can anyone tell me what im doing wrong here?
Thanks!
You don't need the leading / on the view name, i.e. you should return fragments :: nodeList rather than /fragments :: nodeList. Having made this change Thymeleaf should be able to find the template when run from your IDE or from a jar file.
If you're interested, here's what's happening under the hood:
The view name is used to search for a resource on the classpath. fragments :: nodeList means that the resource name is /templates/fragments.html and /fragments :: nodeList means that the resource name is /templates//fragments.html (note the double slash). When you're running in your IDE the resource is available straight off the filesystem and the double slash doesn't cause a problem. When you're running from a jar file the resource is nested within that jar and the double slash prevents it from being found. I don't fully understand why there's this difference in behaviour and it is rather unfortunate. I've opened an issue so that we (the Spring Boot team) can see if there's anything we can do to make the behaviour consistent.
It's an old topic, but I stumbled upon it while having problem with similar symptoms and different root cause. Wanted to share solution which helped me in case it could help somebody else...
Apparently name of the messages.properties file is case sensitive, but not everywhere. I had mine called "Messages.properties" (with capital M) and it worked just fine from inside IDE (IntelliJ), but once I tried to run app from jar, all messages were replaced with ??parameter.name??. Replacing M with lowercase m resolved the problem.

How can I ban a Maven dependency where the version contains a certain part?

I'm tryin to use Maven Enforcer's banned dependencies where I want to ban that there are compile and runtime dependencies to any artifact that contains -redhat-. The background of this: The JEE API and other stuff already exists in the JBoss AS and should never be included in the EAR.
This is what I'm trying, but it doesn't work:
<execution>
<id>banned-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<searchTransitive>false</searchTransitive>
<excludes>
<exclude>*:*:*-redhat-*:*:compile</exclude>
<exclude>*:*:*-redhat-*:*:runtime</exclude>
</excludes>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
As you have discovered this wont work the way you are wanting. (I presume you are finding that the enforcer plugin is matching all dependencies listed in your pom?)
The problem is that Maven expects the version given to either be a single * or to conform to maven's Version Spec. (i.e. 1.0, [1.0,) etc) It can't handle the multiple wildcards that you are using.
Unfortunately I don't really have a solution for you. You could potentially
Write Your Own Rule and extend the BannedDependencies rule and have it work the way you would like.
What follows is a dive into the code that is causing your issue
In the BannedDependencies class there is the following check for the version given in the exclude string:
if (pattern[2].equals("*") || artifact.getVersion().equals(pattern[2]) ) {
result = true;
} else {
try {
result = AbstractVersionEnforcer.containsVersion(
VersionRange.createFromVersionSpec(pattern[2]),
new DefaultArtifactVersion(artifact.getBaseVersion()));
} catch ( InvalidVersionSpecificationException e ) {
throw new EnforcerRuleException("Invalid Version Range: ", e);
}
}
The specific problem for you is
AbstractVersionEnforcer.containsVersion(
VersionRange.createFromVersionSpec(pattern[2]),
new DefaultArtifactVersion(artifact.getBaseVersion()))
You can see that it is expecting a VersionRange due to VersionRange.createFromVersionSpec(). The code for that can be seen here:
VersionRange source code

How to make wro4j-maven-plugin fail the build when a preprocessor fails?

I am using the wro4j-maven-plugin for preprocessing my .js, .css and .less resources.
When a preprocessor fails, like when a .less file contains a syntax error, the plugin just outputs a stacktrace in the build and keeps on building.
This results in having to monitor the build process, or risk having broken resources. Is there any way to make this plugin failOnError like one would do with an AntRun?
pom.xml:
<plugin>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>1.4.5</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<minimize>true</minimize>
<jsDestinationFolder>${basedir}/WebContent/resources/min/js/</jsDestinationFolder>
<cssDestinationFolder>${basedir}/WebContent/resources/min/css/</cssDestinationFolder>
<contextFolder>${basedir}/WebContent/</contextFolder>
<wroFile>${basedir}/WebContent/WEB-INF/wro.xml</wroFile>
<extraConfigFile>${basedir}/WebContent/WEB-INF/wro.properties</extraConfigFile>
<ignoreMissingResources>false</ignoreMissingResources>
<wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
</configuration>
</plugin>
wro.properties:
preProcessors=cssUrlRewriting,cssImport,yuiJsMin
postProcessors=lessCss,yuiCssMin
The default behavior of the lessCss processor when an exception occurs is to abort the processing and leave the resource unchanged. The reasoning behind this is that when a valid css is processed with lessCss, it may fail because it has invalid syntax from Less point of view. This usually happens when you process mixed resources (css & less).
The next wro4j version (1.4.7) will change the default behavior when dealing with exceptions during resource proccessing. Thus, when an exception will occur - the overall processing will fail (it will be possible to configure this behavior).
There is a workaround for earlier versions (including 1.4.5). You can extend the LessCssProcessor and override the onException method. Example:
/**
* Invoked when a processing exception occurs.
*/
protected void onException(final WroRuntimeException e) {
throw e;
}
By using this new processor instead, your build will fail anytime the processor will fail.

How to pass input from command line to junit maven test program

I wrote a junit test to add two numbers. I need to pass this numbers from command line. I am running this junit test from maven tool as
mvn -Dtest=AddNumbers
My test program looks like this
int num1 = 1;
int num2 = 2;
#Test
public void addNos() {
System.out.println((num1 + num2));
}
How to pass these numbers from command line?
Passing the numbers as system properties like suggested by #artbristol is a good idea, but I found that it is not always guaranteed that these properties will be propagated to the test.
To be sure to pass the system properties to the test use the maven surefire plugin argLine parameter, like
mvn -Dtest=AddNumbers -DargLine="-Dnum1=1 -Dnum2=2"
To pass input from command line to junit maven test program you follow these steps. For example if you need to pass parameter fileName into unit test executed by Maven, then follow the steps:
In the JUnit code - parameter will be passed via System properties:
#BeforeClass
public static void setUpBeforeClass() throws Exception {
String fileName = System.getProperty("fileName");
log.info("Reading config file : " + fileName);
}
In pom.xml - specify param name in surefire plugin configuration, and use {fileName} notation to force maven to get actual value from System properties
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- since 2.5 -->
<systemPropertyVariables>
<fileName>${fileName}</fileName>
</systemPropertyVariables>
<!-- deprecated -->
<systemProperties>
<property>
<name>fileName</name>
<value>${fileName}</value>
</property>
</systemProperties>
</configuration>
</plugin>
In the command line pass fileName parameter to JVM system properties:
mvn clean test -DfileName=my_file_name.txt
You can pass them on the command line like this
mvn -Dtest=AddNumbers -Dnum1=100
then access them in your test with
int num1=Integer.valueOf(System.getProperty("num1"));

Resources