Getting name of last folder from maven ${project.basedir} - maven

I have the same question for Maven that someone had about Ant (How can I get the name of the last folder in my basedir path in Ant?).
How do you get just the last directory name from the variable ${project.basedir}?
For example, if my pom.xml is in:
/home/me/project/pom.xml
Then ${project.basedir} = /home/me/project/
I want just the directory name 'project'.
Thanks!

Use: ${project.file.parentFile.name}
How to work it out:
The ${project} actually resolved to a MavenProject object. From there, you can just use bean properties to get the value you need. In this case:
use the file property (through getFile())
use the parentFile property on java.io.File (through getParentFile())
use the name property of the File to get just the name without path information (through getName())
(edit: after comment)
It's not a good idea to use properties for artifact IDs. The ${project.file.parentFile.name} property cannot be resolved when using it as part of artifactId, however some properties do work (project.groupId for the artifactId seems to work).
However, this is not recommended. In fact, if you use any property for the artifact ID instead of a constant, you'll get a warning when you build your project:
[WARNING] Some problems were encountered while building the effective model for <your groupID>:<your artifactID>:jar:1.0-SNAPSHOT
[WARNING] 'artifactId' contains an expression but should be a constant. # <your groupID>:<your artifact ID>:1.0-SNAPSHOT, <basedir>/pom.xml, line 5, column 14
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.

Related

Could not get unknown property 'a.b.c' for root project

I got some source code and was asked to build it. It was a Gradle project. So I changed to the project directory and ran:
$ gradle clean assemble
and the following error came up:
...
* What went wrong:
A problem occurred evaluating root project 'pcase'.
> Could not get unknown property 'postgresql.jdbc' for root project 'pcase' of type org.gradle.api.Project.
...
There is a settings.gradle file in the project folder too. It contains:
rootProject.name = 'pcase'
I took a look at build.gradle and found lots of occurrences like
${project['x']}
For example:
buildscript {
dependencies {
...
// FlywayDB, JOOQ.
classpath "org.postgresql:postgresql:${project['postgresql.jdbc']}"
classpath "org.flywaydb:flyway-gradle-plugin:${project['flywaydb.plugin.version']}"
classpath "nu.studer:gradle-jooq-plugin:${project['jooq.plugin.version']}"
...
What could be ${project['x']}? Looks like associative array in bash and the build script tries to get the value of the key 'x'.
But I didn't find the place in code where this array would be declared and initialized.
The question is: Is the project buildable or is it better to consult the company that worked at it before me?
From the information provided, the project is perfectly buildable, to some certain extend. First of all, project['a.b.c'] is Groovy syntax to access properties from the project object. They're referred to as project properties.
They can be set via
Project properties via command line: gradle -Ppostgresql.jdbc=x.y.z
System properties via command line: gradle -Dorg.gradle.project.postgresql.jdbc=x.y.z
System properties via gradle.properties: org.gradle.project.postgresql.jdbc=x.y.z
All 3 properties (postgresql.jdbc, flywaydb.plugin.version, jooq.plugin.version) denote the version numbers of the particular build script dependencies. However, which versions to use best is beyond my knowledge. I would certainly consult the respective project websites, Maven artifact search or simply ask the company.
org.postgresql:postgresql is the database JDBC driver and certainly depends on the database version.
org.flywaydb:flyway-gradle-plugin is for database migrations. Try with the latest version.
I wasn't able to find gradle-jooq-plugin on Maven central. It's most likely available on the Gradle Plugin Portal.

Add dependency to Maven pom file using org.apache.maven.Model

I’m trying to add dependency to maven pom.xml file using approach described in this post…
def model = readMavenPom file: 'pom.xml'
dep = [
groupId : "org.foo",
artifactId : "bar"
]
model.addDependency(model.&addDependency.parameterTypes[0].newInstance(dep))
…but I’m facing an error which sounds like:
Groovy.lang.MissingMethodException: No signature of method: java.lang.Class.newInstance() is applicable for argument types: (java.util.LinkedHashMap) values: [[groupId:org.foo, artifactId:bar]]
Possible solutions: newInstance(), newInstance(), newInstance([Ljava.lang.Object;), isInstance(java.lang.Object)
What am I doing wrong? I spent 7 days for now trying to fix this thing and add dependency to pom file, but no luck. The only emergency exit here is to replace file contents using shell script, but it’s the least wanted solution. Yes, I can also parse xml file using groovy methods, but it’s not what we wanted, too.

Drools 7.7.0.Final generateModel fails with line and column information but no file information

I'm trying to build a kjar from our existing drools project with lots of individual rules file.
To speed up deployment I would like to generate the model into the kjar as introduced with Drools 7.7.0.Final.
The command I use is: mvn clean install -DgenerateModel=WITHDRL -X
Pretty soon I get an error message:
[ERROR] Failed to execute goal org.kie:kie-maven-plugin:7.7.0.Final:generateModel (default-generateModel) on project foobar: Execution default-generateModel of goal org.kie:kie-maven-plugin:7.7.0.Final:generateModel failed: (line 1,col 33) Parse error. Found ",", expected one of "%=" "&=" "*=" "++" "+=" "--" "-=" "/=" ";" "<<=" "=" ">>=" ">>>=" "^=" "|="
[ERROR] Problem stacktrace :
[ERROR] org.drools.javaparser.GeneratedJavaParser.generateParseException(GeneratedJavaParser.java:11460)
There is no information in which file this error occured. Since our project contains >300 DRL Files it is a bit hard to find the culprit.
Is there any way to get more information out of the Drools Maven Plugin on which file is causing the issue?
That's bug of kie-maven-plugin.
There are the bug's JIRA below.
DROOLS-3505
DROOLS-3523
If dialect is java and your rules have connect expressions with "comma" inside a modify block, The workaround is that
property inside modify block one by one.
the other workaround is changing dialect to mvel.
But, you have to write 'dialect "mvel"' in each rule file.
because dialect species isn't shared in package.

Is there a way to post-process project generated from archetype?

Say I have an archetype and I generate a project from it. But I would like to resolve placeholders in a property file of the project I generated on after generation time by passing the value for placeholder through command line.
For example having the following command line:
mvn archetype:create -DarchetypeGroupId=... -DarchetypeArtifactId=... -DarchetypeVersion=1.0 -DgroupId=... -DartifactId=my-project -Dversion=1.0-SNAPSHOT -Dhello=Hello!
say the archetype contains app.properties (as part of project which is being generated) with the following content:
greeting=${hello}
Is it possible to replace ${hello} with "Hello!" right after project has been generated as a result of mvn archetype:create command?
Yes this is possible. From the advanced usage guide for maven archetypes:
If the user wants to customize the generated project even further, a groovy script named archetype-post-generate.groovy can be added in src/main/resources/META-INF/. This script will end up in the generated archetype's META-INF folder and will be executed upon creating a project from this archetype. This groovy script has access to the ArchetypeGenerationRequest object, as well as all the System.getProperties() and all the archetype generation properties the user has specified.
You could define additional properties in the archetype, following the format:
https://maven.apache.org/archetype/maven-archetype-plugin/specification/archetype-metadata.html
For example:
define the file: src\main\resources\META-INF\maven\archetype-metadata.xml
<archetype-descriptor
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
name="modelant.metamodel.api">
<requiredProperties>
<requiredProperty key="package"><defaultValue>${groupId}.${artifactId}</defaultValue></requiredProperty>
<requiredProperty key="parentGroupId"><defaultValue>${groupId}</defaultValue></requiredProperty>
<requiredProperty key="parentArtifactId"><defaultValue>${artifactId}</defaultValue></requiredProperty>
<requiredProperty key="parentVersion"><defaultValue>${version}</defaultValue></requiredProperty>
<requiredProperty key="metamodelUrl"/>
</requiredProperties>
</archetype-descriptor>
Here you see that it defines additional required properties, so they have to be mandatorily provided within the dialog, where:
some properties may have no value - see metamodelUrl
some properties may have default values either
-- as static text
-- or referring the values of the previously defined standard properties: groupId, artifactId, version
some poperties may override the values of the standard properties - the "package" property. Here it is redefined.
Please note:
the https://maven.apache.org/archetype/maven-archetype-plugin/advanced-usage.html Apache maven page on archetypes refers just calling "mvn install" in order to publish the artifact in the local repository. This is not enough - use: mvn clean install "archetype:update-local-catalog"
the https://maven.apache.org/archetype/archetype-models/archetype-descriptor/archetype-descriptor.html Apache maven page states that the proeprties are referred using "property name" expressions. This is not correct - the properties are allowed to be used in the filtered resources, treating them as velocity templates, thus the references are ${property name} and #if, #for, etc. statements could be used there
Not sure I understood correctly. For post processing after project creation you could use the param -Dgoals and invoke your custom plugin.
Am not sure about your requirement, but why cant you do the same during the project generation itself ?

Maven Scriptlets

when I am builting my project in NetBeans using Maven I get this warning message:
[WARNING] DEPRECATED [postinstallScript]: Use postinstallScriplet
[WARNING] DEPRECATED [preinstallScript]: Use preinstallScriplet
[WARNING] DEPRECATED [preremoveScript]: Use preremoveScriplet
I change
<preinstallScript>src/main/scripts/preinstall</preinstallScript>
<postinstallScript>src/main/scripts/postinstall</postinstallScript>
<preremoveScript>src/main/scripts/preremove</preremoveScript>
to
<preinstallScriptlet>src/main/scripts/preinstall</preinstallScriptlet>
<postinstallScriptlet>src/main/scripts/postinstall</postinstallScriptlet>
<preremoveScriptlet>src/main/scripts/preremove</preremoveScriptlet>
in pom.xml. Then I got this error:
[ERROR]BUILD ERROR
------------------------------------------------------------------------
Failed to configure plugin parameters for: org.codehaus.mojo:rpm-maven-plugin:2.0.1
(found static expression: 'src/main/scripts/postinstall' which may act as a default value).
Cause: Cannot assign configuration entry 'postinstallScriptlet' to 'class org.codehaus.mojo.rpm.Scriptlet' from 'src/main/scripts/postinstall', which is of type class java.lang.String
and project was not built. What's wrong with this?
Thanks in advance.
You probably need to use it like this:
<preinstallScriptlet>
<scriptFile>src/main/bin/preinstall.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</preinstallScriptlet>
(as per: http://www.mojohaus.org/rpm-maven-plugin/adv-params.html )

Resources