apache / apache/maven-archetype

[ARCHETYPE-613] Different gererating result with user defined parameters

Open
#834 1 comment 0 reactions 0 assignees View on GitHub
bug priority:major
Dominant language
Java
Stars
148
Forks
181
Avg merge
1d 20h
Merged PRs (30d)
8

Description

**[Liu Shilong](https://issues.apache.org/jira/secure/ViewProfile.jspa?name=jxsrlsl1234)** opened **[ARCHETYPE-613](https://issues.apache.org/jira/browse/ARCHETYPE-613?redirect=false)** and commented

Happend in two different maven version 3.6.1 and 3.6.3,

I defined my archetype-metadata.xml as following:

```java
//代码占位符




1.0.0-SNAPSHOT



//user defined parameter
// user defined parameter
${package.getClass().forName("org.apache.velocity.util.StringUtils").nullTrim("")} //default is null;


```

 and following are some others parameter tansformed by abover parameters

```java
//代码占位符

${xxxx1.toUpperCase()}

${xxxx1.toLowerCase().substring(0,1).toUpperCase()}${xxxx1.toLowerCase().substring(1)}

${package.getClass().forName("org.apache.velocity.util.StringUtils").nullTrim("$xxxx2").toUpperCase()}

${package.getClass().forName("org.apache.velocity.util.StringUtils").firstLetterCaps("${xxxx2}_").replaceAll("_","")}

${xxxx4}${xxxx6}

....

```

when I use command "mvn archetype : generate ...." in maven 3.6.3, i got the right generated project ,and all the parameters are as my expected including parameters which need to be evaluated. But in maven 3.6.1(In fact , I'm not sure whether the version cause the difference"), it's different, some parameters are not evaluatedd correctly like following:

```java
//代码占位符
...
Parameter: xxxx3, Value: ${xxxx1.toUpperCase()}
[INFO] Parameter: xxxxx6, Value: _${xxxx}_
[INFO] Parameter: xxxxx, Value: _xxxx_
...
```

as you see, some parameters are evaluated, but some are not.  In fact , I found this happened also in 'mvn command' and 'maven archetype generating process in IDEA'. And I found following source code in maven-archetype plugin:

```java
//代码占位符
private Context prepareVelocityContext(ArchetypeGenerationRequest request) {
Context context = new VelocityContext();
context.put(Constants.GROUP_ID, request.getGroupId());
context.put(Constants.ARTIFACT_ID, request.getArtifactId());
context.put(Constants.VERSION, request.getVersion());
context.put(Constants.PACKAGE, request.getPackage());
final String packageInPathFormat = getPackageInPathFormat(request.getPackage());
context.put(Constants.PACKAGE_IN_PATH_FORMAT, packageInPathFormat);

if (getLogger().isInfoEnabled()) {
getLogger().info("----------------------------------------------------------------------------");

getLogger().info(
"Using following parameters for creating project from Archetype: " + request
.getArchetypeArtifactId()
+ ":" + request.getArchetypeVersion());

getLogger().info("----------------------------------------------------------------------------");
getLogger().info("Parameter: " + Constants.GROUP_ID + ", Value: " + request.getGroupId());
getLogger().info("Parameter: " + Constants.ARTIFACT_ID + ", Value: " + request.getArtifactId());
getLogger().info("Parameter: " + Constants.VERSION + ", Value: " + request.getVersion());
getLogger().info("Parameter: " + Constants.PACKAGE + ", Value: " + request.getPackage());
getLogger().info("Parameter: " + Constants.PACKAGE_IN_PATH_FORMAT + ", Value: " + packageInPathFormat);
}

for (Iterator iterator = request.getProperties().keySet().iterator(); iterator.hasNext(); ) { // here,the result of request.getProperties() is a hashtable
String key = (String) iterator.next();

String value = request.getProperties().getProperty(key);

if (maybeVelocityExpression(value)) {
value = evaluateExpression(context, key, value);
}

context.put(key, value);

if (getLogger().isInfoEnabled()) {
getLogger().info("Parameter: " + key + ", Value: " + value);
}
}
return context;
}
```

As above comment, the result of request.getProperties() is a HashTable, the fact is that the parameter order is not what we input but hash value, so it cause that some parameters are not evaluated because some parameters are relied on others.

But the question is "how difference happens?" . In fact ,once the parameter are determined, the result will be determined, why it will be different in some case?

IDEA use the java command to start the process of generating like:

```java
//代码占位符
java -Dxxx=xxx org.apache.maven.plugins:maven-archetype-plugin:RELEASE:generate
```

also, some parameters are not evaluated correctly.

---

**Affects:** 3.2.0

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with prepareVelocityContext in the maven-archetype plugin and the evaluateExpression call that processes request.getProperties(). Reproduce the generation with Maven 3.6.1 and 3.6.3 using dependent user-defined parameters, then verify that parameter evaluation is deterministic regardless of property iteration order.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.