Maven - parsing command line arguments? - java

Can anyone think of a way to do this? At the request of our build engineers, I have parameterized a Maven build of mine like this:
mvn clean install -Dmyprop1=kimi -Dmyprop2=seb -Dmyprop3=alonso
These line up with some properties I've defined in my pom, like this:
<properties>
<myprop1>default value for prop1</myprop1>
<myprop2>default value for prop2</myprop3>
<myprop3>default value for prop3</myprop4>
</properties>
In my pom, I can then of course refer to these properties anywhere I'd like - for exampe:
${myprop2}
AFAIK, this is all pretty standard Maven stuff for handling custom command line args, but here is where my question comes in - what our build engineers would actually like to see is something more along the lines of:
mvn clean install -Dmyprops=prop1>kimi,prop2>seb,prop3>alonso
In other words, a single command line argument that they could stuff all of the properties into (using some sort of delimiting scheme, like ">" and "," for instance as I've shown above) that I would then be expected to parse within my pom accordingly.
I've done a fair amount of research and I'm really not seeing anything that would allow me to do this & I'm inclined to push back and tell our build engineers they need to just update their machinery to handle multiple command line args (1 per property, as would be standard).

Related

When specifying -javaagent, is it possible to have a jarpath containing = (equal) in it?

Question
Is it possible to use a jarpath containing an equal sign when specifying an agentlib ? For example, using some kind of escaping ?
Note: the syntax to specify the java agent is -javaagent:jarpath[=options] (see the official documentation).
Context
I have a Continuous Integration setup where paths contains an = (equal) sign.
And I have problems running the maven surefire plugin which fails at startup because the agent jar is not found.
I dig a bit and found that
And our command line looks like /<path-to-jre>/bin/java -javaagent:/<path-to-jenkins-workspace>/myProject=myJobName/.repository/org/jacoco/org.jacoco.agent/0.7.9/org.jacoco.agent-0.7.9-runtime.jar=destfile=/<path-to-jenkins-workspace>/myProject=myJobName/target/jacoco.exec,append=true <other arguments to java dropped>.
I made this command work by renaming the project to myProject+myJobName, thus I'm sure that the problem lies with the use of equal.
Note that the above command line is directly generated by maven-surefire-plugin, thus I don't have many options to alter it.
According to Sylvain's comment, this is not possible with OpenJDK 9.
This is probably the same with earlier JDK and the one from Oracle

Passing data/strings from Maven to Java/JUnit app?

I have Eclipse and also installed manually Maven on win7-64 machine.
I need to be able to pass data to the Java and Java/JUnit test app.
It works in the console. F.e. if I do :
mvn -Dvar1=blah1 -Dvar2=blah2 test
I can read the data in the Java/Junit code like this :
String var1 = System.getPropertiy("var1")
String var2 = System.getPropertiy("var2")
But if I do "maven test" with the Eclipse "internal" maven (m2e) and ofcourse specify "-Dvar1=blah1 -Dvar2=blah2" in VM-properties in the Run-as box, the values are "null" when I try to print them.
Can you point me to what to look for, so I can solve this problem.
(It has to work in both environments).
Btw. I don't add anything to pom.xml to make this work in the first case.
I'm saying this because the Q/A I see that closely resemble my problem, seems to imply I have to add something to pom.xml!!
My more broad question is passing small configuration tokens of data via this properties-mechanism the best-practice, correct method to do that.
I'm not sure, I understood your question correctly. I'm speculating that you are having trouble in passing params for 'maven test' in eclipse.
If so, Run As --> Run Configurations --> Create a new maven configuration from 'Maven Build' on left pane
In 'Main' tab, choose your project --> Then use 'Add' button below to add parameters. Then you will be able to read those params as system properties in program

What is build-by-convention in Gradle deep explanation?

The Gradle User Guide often mentions that Gradle is declarative and uses build-by-convention. What does this mean?
From what I understand it means that, for example, in java plugin there are conventions like
source must be in src/main/java,tests must be in src/main/test, resources in src/main/resources, ready jars in build/libs and so on. However, Gradle does not oblige you to use these conventions and you can change them if you want.
But with the first concept, I have a bigger problem with understanding. Like SQL you say what you want to do with your queries but do not say how the Database System will get them, which algorithm to use to extract the data etc.
Please, tell me more to understand these concepts properly. Thanks.
Your understanding of build by convention is correct, so I don't have to add anything there. (Also see Jeff's answer.)
The idea behind declarative is that you don't have to work on the task level, implementing/declaring/configuring all tasks and their dependencies yourself, but can work on a higher, more declarative level. You just say "this is a Java project" (apply plugin: "java"), "here is my binary repository" (repositories { ... }), "here are my sources" (sourceSets { ... }), "these are my dependencies" (dependencies { ... }). Based on this declarative information, Gradle will then figure out which tasks are required, what their dependencies are, and how they need to be configured.
In order to understand a declarative style of programming it is useful to compare and contrast it against an imperative programming style.
Declarative Programming allows us to specify what we want to get done.
In Imperative Programming we specify how we get something done.
So when we use gradle,as Peter describes, we make declarations, declaration such as, "This is a Java Project" or "This is a Java Web Application"
Gradle then, makes use of plugins that offer the service of handling the building of things like "Java Projects" or "Web Applications". This is nice because it is the Gradle Plugin that contains the implementation details that concerns itself with such tasks as compiling java classes and building war files.
Contrast this against another build system, Make, which is more imperative in nature. Lets take a look at a simple Make rule from taken from here:
foo.o : foo.c defs.h
cc -c -g foo.c
So here, we see a rule that describes how to build an object file foo.o from a C source file and a C header file.
The Make rule does two things.
The first line says that a foo.o file depends on a foo.c and foo.h. This line is kind of declarative in so far as Make knows how to check the timestamp on the file foo.o to see if it is older than the files foo.c and foo.h. and if foo.o is older then Make will invoke the command that follows on the next line.
The next line is the imperative one.
The second line specifies exactly what command to run (cc - a C compiler) when a foo.o file is older than either of the files foo.c or foo.h. Note also that the person who is writing the Makefile rule must know what flags that are passed to the cc command.
Build by convention is the idea that if you follow the default conventions, then your builds will be much simpler. So while you can change the source directory, you don't need to explicitly specify the source directory. Gradle comes with logical defaults. This is also called convention over configuration.
This part edited to be more clear about declarative nature based on Peter's answer:
The idea of the build being declarative is that you don't need to specify every step that needs to be done. You don't say "do step 1, do step 2, etc". You define the plugins (or tasks) that need to be applied and gradle then builds a task execution graph and figures out what order to execute things in.

Hudson's FindBugs plugin reports line number "-1" for bugs. Ideas?

Greetings,
I have a simple test project set up in Hudson and the project's build process (a batch file) generates a findbugs.xml file. This is processed by Hudson's FindBugs plugin but it shows the line number of the bugs as "-1" instead of their actual line number. A coworker suggested I enable debug info for the compiler. I used the -g "Generate all debugging info" option for javac but nothing seemed to change. My build command is:
javac -g -classpath C:\testWebApp1\src -d C:\testWebApp1\build C:\testWebApp1\src\*.java
The only other thing in the build.bat file is a call to the FindBug tool (text UI). Here is what the FindBugs Plugin says about the first bug:
File: GenerateHellos.java, Line: -1, Type: UUF_UNUSED_FIELD, Priority: Normal, Category: PERFORMANCE
Any ideas? Thanks a ton!
This is half of an answer:
You have an unused field declared in that class. FindBugs uses static analysis of byte code to find bugs; unfortunately, the byte code format does not store line numbers for class or member fields, so FindBugs can't actually report a line number. There's got to be some switch that will allow it to output more helpful information (i.e. the name of the field), but I have no idea.
Alternatively, you might try PMD, which is a lot noisier, but actually analyzes the source code and also integrates with Hudson.
Did a little more digging and it looks like this is probably a bug in the inspector for that bug pattern. Assuming that your FindBugs run is configured with a n appropriate source directory (i.e., using -sourcepath), the majority of the bugs found should have line numbers associated with them. To check this, open the outputted report. You should see elements like the following:
<!-- skipping a bit -->
<BugInstance type="...">
<Class classname="com.example.MyClass">
<!-- ... -->
</Class>
<!-- ... -->
<SourceLine classname="com.example.MyClass" start="5" end="5" sourcefile="MyClass.java"/>
</BugInstance>
The key there is the <SourceLine classname="..."/>, which reports the line number that the bug was found on. For numerous other inspections, including those for unread fields and a couple of other cases where their are no line numbers in the byte code, this line is filled in correctly, but not for UUF_UNUSED_FIELD. Hence, the Hudson plugin is doing the sensible thing and reporting line = -1.
The Eclipse plugin, however, which has access to Eclipse's rich metadata about the source code is able to locate the field by matching the field name, hence, it appearing to work in Eclipse (if you delete the field in question in Eclipse you should see the bug show up on the first line of the file; other bugs show up on the line number specified in the XML report).
No fix, but hopefully that clarifies what is happening.
You are almost there with the -g. Findbugs is based on bytecode analysis, and depends on the debugging information that is in the class files, your coworker is right about that.
You also need to clean out any previously generated class files, as the compiler is based on timestamps, and won't regenerate files that appear up-to-date.

maven ${user.home} not being resolved correctly

I've got the following line in my pom.xml:
<updateRepositoryURL>file:/${user.home}/.m2/repository/repository.xml</updateRepositoryURL>
and when I am attempting to use it within my program the resultant string is:
file:/c:Documents and Settings<myusername>/.m2/repository/repository.xml
where <myusername> is my user name funnily enough.
however it should be
file:/c:/Documents and Settings/<myusername>/.m2/repository/repository.xml
Does anyone out there have any ideas as to why it is not resolving properly?
Thanks in advance
This might be a bug in maven. I've bookmarked this workaround some time ago:
I found a handy way to reference the
Java system property ${user.home}
within a Maven build that supports
Windows' ridiculous path name to
home/profile directories:
c:\Documents and Settings\foobar.
The problem is, when using Maven, this
parameterized property doesn't get
passed through as one property value,
but as three, because somewhere in the
build Maven chokes on the spaces or
back-slashes and interprets it as
either three arguments:
"c:\Documents", "and", "Settings\foobar"
or treats the windows back-slash as an
escape character and removes them so
my parameterized user.home becomes:
"c:Documents and Settingsfoobar"
[...]
However, on Windows XP, unless I set
the user.home on the build path every
time, the back-slash escaping or space
issues cause the files to not be
found.
To fix it, add this profile to the
$M2_HOME/conf/settings.xml file:
<profile>
<id>laptop-xp</id>
<properties>
<user.home>C:/Documents and Settings/${user.name}</user.home>
</properties>
</profile>
Then add an appropriate entry to the
activeProfiles:
<activeProfile>laptop-xp</activeProfile>
Now every user will be able to use the
user.home property to reference
their home path correctly on the
Windows box.
Or, you're just another victim of this bug: http://bugs.sun.com/view_bug.do?bug_id=4787931. It's a very old bug (more than 6 years old) that affects all versions up till Java 1.6.x.
Another workaround could be to correct or produce the path via the Groovy GMaven plugin, similar to this groovy code:
System.setProperty(
'user.home.fixed',
System.getProperty('user.home').replaceAll( '\\\\', '/' ) )
Maybe one could even override user.home, but I am not sure if it would work. So using ${user.home.fixed} everywhere instead of ${user.home} should work then if executed in an early phase.

Categories

Resources