我正在创建一个原型,并希望创建一个项目范围内的可用属性,其中包含当前日期和工件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
就像一个魅力,但ldt
,dtf
和date
似乎不起作用,给出错误:
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")
(有趣的是,pkgClass
和strClass
都应该是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文件),我们将非常感激。
答案 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>
表达被评估。