Force Maven to use System's javac - maven

I have made some code changes to javac and would like maven to use the version of javac that I changed. Unfortunately, it appears that maven ships its own javac implementation. How can I get maven to compile sources using the system wide javac (the one that is executed when running javac in the shell).
Without really knowing what these options mean, I tried providing the fork, and forceJavacCompilerUse which I found here: http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html
But they do not appear to help at all.

You're in the right ballpark. Look here:
http://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html
To avoid hard-coding a filesystem path for the executable, you can use
a property. For example:
<executable>${JAVA_1_4_HOME}/bin/javac</executable>
Each developer then defines this property in settings.xml, or sets an
environment variable, so that the build remains portable.
<settings>
[...]
<profiles>
[...]
<profile>
<id>compiler</id>
<properties>
<JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
</properties>
</profile>
</profiles>
[...]
<activeProfiles>
<activeProfile>compiler</activeProfile>
</activeProfiles>
</settings>
If you build with a different JDK, you may want to customize the jar
file manifest.
I believe the key is setting an explicit <executable>. And I suspect it can probably be hard-coded, without messing with environment variables or other clauses.
See also this link, and look at the "executable" in the sample pom.xml:
Where is the JDK version to be used by Maven compiler specified?

I believe maven looks for JVA_HOME for finding the java. So when you set it to your specific java maven should be able to use it

Related

In maven, can I define a variable used in another pom?

I'm getting an error when running maven build (unable to load a dependency).
[ERROR] Failed to execute goal on . . .
Could not transfer artifact my.group:libme1:${someVariable} from/to . . .
I believe that the developer that published this artifact was supposed to be setting the variable ${someVariable} but didn't. I think this is a bug but I'm trying to work around it by setting the variable.
The POM for the JAR I'm depending on my.group:libme1:1.2.3 looks like this (snippet highlighting the issue):
<groupId>my.group</groupId>
<artifactId>libme1</artifactId>
<parent>
<groupId>my.group</groupId>
<artifactId>libme1-parent</artifactId>
<version>${someVariable}</version>
</parent>
I tried defining it by adding -DsomeVariable=1.2.3 on the command line but it didn't work. For example, this command
mvn -DsomeVariable=1.2.3 clean install
should work based on Baeldung's article but doesn't.
I also ran:
mvn -DsomeVariable=1.2.3 help:effective-pom
and I see the variable being set, so I know he POM I'm using has that defined, but for some reason another POM doesn't pick up that value (or that is how it appears to me).
Is there any way to set the variable so it can be used in another POM? I'm guessing this is not possible.
Searching for an answer I found:
The maven doc
https://maven.apache.org/settings.html#Activation
If you know that this is bug, please let me know. I'm also reaching out to the publish of the artifact to ask them how this is supposed to work.
Basically the dependency's pom is invalid, the reasoning is following:
maven allows developers to do following things:
define dependencies in parent pom
impose restrictions on dependencies via <dependencyManagement> in both current and parent pom
use placeholders ${...} in <version> element, which somehow get resolved via system properties and current/parent pom properties
all those features mentioned above are very convenient from development perspective, however when you publish artifacts those features cause a pain in behind: that became not possible to use external library without it's parent pom, because parent pom may define dependencies and properties.
In your particular case someone have define version of parent pom as ${someVariable}, that in turn means it is not possible to use that library without information about the value of ${someVariable}. However, even if you had known the "correct" value of ${someVariable} and might specify it via system properties, that would cause some weird behaviour: today you may specify one value for ${someVariable}, tomorrow you (or someone else) will specify another value and ultimately you will get different builds, due to that maven denies such configurations (that is much better to fail a build rather than build something unreliable), that would be wiser to initially deny publishing such poms, but we have what we have.
It might be that the variable was stored in some user's settings.xml.
This would allow checking out an older version already in production for writing patches.
<settings>
...
<profiles>
<profile>
<id>work-in-progress</id>
<properties>
<someVariable>1.2.3</someVariable>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>work-in-progress</activeProfile>
</activeProfiles>
</settings>
So you might do that too. And search in users' directories, .m2 repo directories where usually the settings.xml is stored.

Custom alternative configurations for Maven life cycles

How can I add custom alternative configurations to the default life cycles in the pom.xml?
So that I for example can still call mvn package (default behavior), but also mvn quickPackage which runs the default package life cycle, but has e.g. skipTests true and the XML equivalents for other command line parameters...?
All I could find was either directing me into:
Using extra special plugins, even write my own, which I'm not allowed here.
Apply the configuration to everything, or at least always to a certain life cycle. Removing the default behavior of e.g. package.
Do I have to fallback to use command line scripts (which counters the point of having a build management system)? Or is there a pom.xml solution?
You can use Maven Profiles for that, e.g.:
<profiles>
<profile>
<id>quick</id>
<properties>
<bla.bla.bla>true</bla.bla.bla>
<this.that.then>true</this.that.then>
<everything.now>true</everything.now>
<feature.set.extra>true</feature.set.extra>
</properties>
</profile>
</profiles>
Activate it with:
mvn ... -Pquick ...

Setting Environment Variables in Maven pom files

Sorry for asking a question that many will say it has been asked again and again, however I couldn't find a satisfactory or complete answer.
I have to build a maven project. Inside it I have the following:
<profile>
<id>windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<properties>
<weblogic.home>${env.WEBLOGIC_SERVER_HOME}</weblogic.home>
<weblogic.precompilation.java.home>${env.JAVA_64_HOME}</weblogic.precompilation.java.home>
</properties>
</profile>
and I get the error:
[ERROR] 'dependencyManagement.dependencies.dependency.systemPath' for weblogic:weblogic.jar must specify an absolute path but is ${env.WEBLOGIC_SERVER_HOME}/server/lib/weblogic.jar # ..\pom.xml
Of course, by setting the absolute path to the above:
<weblogic.home>c:/Oracle/Middleware/wlserver_10.3</weblogic.home>
the problem is solved, but how can I actually set env.WEBLOGIC_SERVER_HOME in my system so that maven finds it?
I setup a new environment variable:
WEBLOGIC_SERVER_HOME = c:/Oracle/Middleware/wlserver_10.3
in my Windows machine but no luck. I tried setting configuration environmentVariables in maven-surefire-plugin as explained in [How to set up an environment variable in mvn pom? (but didn't pass it via -D in the command line), tried to set a property like here [How to refer environment variable in POM.xml? but no chance.
I thought that once I setup the environment variable (WEBLOGIC_SERVER_HOME) in my OS, I could then access it from my pom using ${env.WEBLOGIC_SERVER_HOME}. But I guess this is not enough.
In my IDE (NetBeans), I cannot set the environment variable for the maven project since it displays the "Resolve Project Problems" dialog box instead.
Any help is appreciated.

Is it possible to use a maven property to activate a profile based upon a file?

I would like to download the JACOB dlls when they're not in my local repository.
As a consequence, I have those two profiles
<profile>
<id>use-jacob-dll</id>
<activation>
<file>
<exists>${settings.localRepository}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</exists>
</file>
</activation>
<dependencies>
<dependency>
<groupId>${jacob.groupId}</groupId>
<artifactId>jacob</artifactId>
<type>dll</type>
<classifier>x64</classifier>
<version>${jacob.version}</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>download-jacob-dll</id>
<activation>
<file>
<missing>${settings.localRepository}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</missing>
</file>
</activation>
But, even when download-jacob-dll has accomplished its goal, a call to mvn help:active-profiles indicates the following
The following profiles are active:
- tests-for-eclipse (source: com.capgemini.admdt:kpitv:1.2.4-SNAPSHOT)
- download-jacob-dll (source: com.capgemini.admdt:kpitv:1.2.4-SNAPSHOT)
I suspect it is due to the fact that I use the ${settings.localRepository} in my activation property.
Question: Is it the cause of the failure? And if so, how can I activate my profile only when dependency is missing ?
Is it possible to use a maven property to activate a profile based upon a file?
No, as stated by the Maven documentation on profiles
Supported variables are system properties like ${user.home} and environment variables like ${env.HOME}. Please note that properties and values defined in the POM itself are not available for interpolation here, e.g. the above example activator cannot use ${project.build.directory} but needs to hard-code the path target.
However, from the POM documentation we also get that
a given filename may activate the profile by the existence of a file, or if it is missing. NOTE: interpolation for this element is limited to ${basedir}, System properties and request properties.
Hence, indeed no Maven properties except ${basedir} are allowed.
And if so, how can I activate my profile only when dependency is missing?
By hardcoded path to the dependency or concerned file would be a solution, even though not portable like the solution you meant.
Alternatively you could use a request property as mentioned by the documentation above, thus need to configure the activation with a property which then must be passed from the command line (more portable but more fragile as well):
<activation>
<file>
<missing>${path}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</missing>
</file>
</activation>
Then invoke maven as following:
mvn clean install -Dpath=path_to_local_rep
The solution above could be reasonable in some contexts like Jenkins jobs.

Maven JAXB plugin and locale for generated output

I'm using the maven-jaxb2-plugin (from org.jvnet.jaxb2.maven2) to generate classes from an XSD schema. All is working fine and the generated classes are all that I need. Except for one thing, all the generated comments inside those classes are using my computer locale (which is french).
I'd like to be able to change the locale of the generated comments (to use english for example). Can it be done through the plugin configuration or the project configuration in the pom.xml ? Or must it be done in my shell when I run the mvn command?
I tried setting the project.build.sourceEncoding but that doesn't change the locale. I tried setting the user.language or user.country but that doesn't have any effect on the output.
There is an option to pass some arguments to the xjc command that I could use, but I cannot find anything related to locale when calling xjc.
The best thing is to put the following into your pom:
<project>
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
...
</project>
The above will also influence the maven-compiler-plugin etc. Furthermore the jaxb2-maven-plugin will also be influenced by the above property (${project.build.sourceEncoding}).

Resources