2017-06-04 52 views
-1

我正在创建一个原型,并且希望创建一个项目范围可用的属性,其中包含当前日期和所有工件ID的小写变体。我发现the following post on Stackoverflow,这表明它通常应该是可能的。为原型maven项目设置动态速度属性

我试着像这样加入这原型-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应该是一个类的对象)。

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

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

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

编辑: 我试着改为创建包含#set指令的generalproperties.vm文件。然后使用#parse(“generalproperties.vm”)将该文件加载到第一行中的每个文件。虽然我确实从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文件),将不胜感激。

回答

1

这应该工作:

... 
<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> 
... 
+0

我仍然收到以下错误:'INFO:Null reference [template'date',第1行,第1列]:$ {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“))}不能我正在使用IntelliJ IDEA 2017.1.3终极版 –

+0

你的maven-archetype-plugin的版本是什么?我使用3.0.1 –

+0

我也在使用该版本。你如何创建你的原型? –

0

我能想到的唯一限制是如果您在Velocity配置属性中使用SecureUberspector而不是标准Uberspector。但是你不能得到java.time.LocalDateTime类,所以情况并非如此,除非你使用的是旧的Velocity版本。使用Velocity 1.7,我可以获得对now()方法的参考并调用它。

另外,你确定直接的Java版本正常工作吗?例如,我在Class.getClassLoader() javadoc中读到:“某些实现可能使用null来表示引导类加载器。如果此类由引导类加载器加载,则此类方法将在此类实现中返回null。“

+0

我使用的是最新版本的Maven原型的,它使用速度1.7我觉得奇怪的是原型的元数据文件和解析的文件之间的矛盾的解析。文件无法获得'now'方法,其中元数据文件甚至无法通过使用'forName'到达该类。任何想法? –