为原型maven项目设置动态速度属性

时间:2017-06-04 03:19:41

标签: java maven metadata velocity maven-archetype

我正在创建一个原型,并希望创建一个项目范围内的可用属性,其中包含当前日期和工件ID的全小写变体等内容。我找到了the following post on Stackoverflow,它显示了通常应该如何实现。

我尝试将其添加到archetype-metadata.xml中,如下所示:

    ...
    <requiredProperty key="artifactIdLower">
        <defaultValue>${artifactId.toLowerCase()}</defaultValue>
    </requiredProperty>
    <requiredProperty key="ldt">
        <defaultValue>${package.getClass().forName("java.time.LocalDateTime").getMethod("now").invoke(null)}</defaultValue>
    </requiredProperty>
    <requiredProperty key="dtf">
        <defaultValue>${package.getClass().forName("java.time.format.DateTimeFormatter").getMethod("ofPattern", $package.getClass().forName("java.lang.String")).invoke(null, "dd MMM yyyy")}</defaultValue>
    </requiredProperty>
    <requiredProperty key="date">
        <defaultValue>${ldt.format($dtf)}</defaultValue>
    </requiredProperty>
    ...

属性artifactIdLower就像一个魅力,但ldtdtfdate似乎不起作用,给出错误:

Null reference [template 'dtf', line 1, column 1] : ${package.getClass().forName("java.time.format.DateTimeFormatter").getMethod("ofPattern", $package.getClass().forName("java.lang.String")).invoke(null, "dd MMM yyyy")} cannot be resolved.

之后我试着看看这个空引用来自链中的哪个位置。我能够将pkgClass设置为$package.getClass()(或$package.Class),

但之后我无法将$strClass设置为$package.getClass().forName("java.lang.String")$pkgClass.forName("java.lang.String")(有趣的是,pkgClassstrClass都应该是Class对象)。

这让我想知道在archetype-metadata.xml中使用反射是否存在限制。

我的问题是:我如何设置可以在项目范围内使用的动态生成的属性值(如上所述)?

我不想在我创建的每个文件中定义这些属性,因为我可能会在以后添加更多属性。

修改: 我试图创建一个包含#set指令的generalproperties.vm文件。然后,使用#parse(&#34; generalproperties.vm&#34;)将第一行上的每个文件加载此文件。虽然我确实从pom.xml文件中获取了要解析的文件,但它并没有像我想要的那样运行。

以下输入

test
$null
#set( $ldtClass = $package.getClass().forName("java.time.LocalDateTime") )
$ldtClass.Name
$ldtClass.getMethod("now")
#set( $ldtNowMethod = $ldtClass.getMethod("now") )
$ldtNowMethod.Name
#set( $clsLoader = $package.getClass().getClassLoader() )
$clsLoader
#set( $ldtClass2 = $clsLoader.loadClass("java.time.LocalDateTime") )
$ldtClass2.Name
$ldtClass2.getMethod("now")
#set( $ldtNowMethod2 = $ldtClass2.getMethod("now") )
$ldtNowMethod2.Name
#set( $ldt = $ldtNowMethod2.invoke($null) )
$ldt
#set( $dtf = $package.getClass().forName("java.time.format.DateTimeFormatter").getMethod("ofPattern", $package.getClass().forName("java.lang.String")).invoke($null, "yyyy/MM/dd HH:mm:ss") )
$dtf

生成以下输出:

test
$null
java.time.LocalDateTime
$ldtClass.getMethod("now")
$ldtNowMethod.Name
$clsLoader
$ldtClass2.Name
$ldtClass2.getMethod("now")
$ldtNowMethod2.Name
$ldt
$dtf

前3个输出符合预期,但在此之后我无法得到我想要的结果。如果有人能够解决上述任何一个问题(使用元数据文件或generalproperties文件),我们将非常感激。

3 个答案:

答案 0 :(得分:2)

这应该有效:

...
<requiredProperty key="date">
    <defaultValue>${package.getClass().forName("java.time.LocalDateTime").getMethod("now").invoke(null).format($package.Class.forName("java.time.format.DateTimeFormatter").getMethod("ofPattern", $package.Class).invoke(null, "dd MMM yyyy"))}</defaultValue>
</requiredProperty>
...

答案 1 :(得分:0)

我能想到的唯一限制是你在Velocity配置属性中使用file_get_contents而不是标准的Uberspector。但是你不可能获得SecureUberspector课程,所以情况并非如此,除非你使用旧的Velocity版本。使用Velocity 1.7,我可以获得对java.time.LocalDateTime方法的引用并进行调用。

另外,您确定直接Java版本正常运行吗?例如,我在now() javadoc中读到&#34;某些实现可能使用null来表示引导类加载器。如果此类由引导类加载器加载,则此方法将在此类实现中返回null。&#34;

答案 2 :(得分:0)

也许它可以帮助我注意到的人。

当我有类似的东西时:

<requiredProperty key="packageId"></requiredProperty>
<requiredProperty key="packageIdInPathFormat">
    <defaultValue>${package.getClass().getMethod("replace").invoke($packageId, ".", "/")}</defaultValue>
</requiredProperty>

它没有评估属性packageIdInPathFormat中的表达式。

但是当我做类似的事情时:

<requiredProperty key="packageId"></requiredProperty>

<requiredProperty key="tempPackageId">
   <defaultValue>${packageId}</defaultValue>
</requiredProperty>

<requiredProperty key="packageIdInPathFormat">
   <defaultValue>${tempPackageId.replace(".", "/")}</defaultValue>
</requiredProperty>

表达被评估。