我想:
我能够生成源代码(上一个列表中的第1项和第2项),但是我无法在输出中指定Java源代码的“包”结构,即我看不到package
Java语句作为生成Java源代码中的第一行代码。我可以指定Frege编译器在哪里放置生成的代码(通过-d
参数)。
我认为这就是为什么在构建可执行Jar时,然后启动它,我看到类似的错误(根据对Gradle任务的不同尝试),例如:no main manifest attribute
。
Frege源代码保存在名为HelloFrege.fr
的文件中,生成的Java源代码位于名为HelloFrege.java
的文件中(我验证了该文件包含预期的main
方法)。
这里有Gradle“Jar任务”的版本:
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Hello Frege Jar Example',
'Implementation-Version': version,
'Main-Class': 'HelloFrege'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
这里有另一个版本的Gradle“Jar”任务:
jar {
manifest {
attributes 'Main-Class': 'HelloFrege'
}
}
我该如何解决这个问题?我想避免手动将包引用添加到自动生成的Java源代码文件中。
答案 0 :(得分:2)
如果Frege中的模块名称不合格,例如HelloWorld
,则不会看到用Java生成的package语句。模块名称将成为类名,包将为空或默认包。
如果您的模块名称是合格的,例如foo.bar.HelloWorld
,那么foo.bar
将是包名称,HelloWorld
将是生成的Java源代码中的类名。
规则是模块名称的最后一部分成为类名,限定符在生成的Java源代码中形成包名。
答案 1 :(得分:1)
我不确定gradle在这方面可以为你做什么,但如果没有gradle,至少应该有以下几点:
... build your jar, as before ...
jar -uvfe project-all.jar HelloFrege
java -jar project-all.jar # run it
当然,这只是创建清单的另一种方式。如果这样做,那么就该研究为什么gradle拒绝这样做了。
Postscriptum:在考虑了问题可能是另一分钟之后,我发现你可能认为源文件名/路径与java包名有关。虽然最好让文件路径与包名匹配,并且文件基名与类名匹配(就像在Java中一样),但在Frege中并非如此。此外,要消除一些混淆,请在frege中使用模块关键字。正如Marimuthu所解释的,Java包和类名是从frege模块名称派生的。
示例:
$ cat Foo.fr
module my.org.Baz where
...
$ java -jar fregec.jar -d bin Foo.fr
这会在包Baz
中生成my.org
类,并在bin/my/org/Baz.class
答案 2 :(得分:0)
到目前为止,我发布了我的调查结果。适用于我的Gradle命令组合如下(从命令行输入gradle clean generateJavaSrcFromFregeSrc fatJar
调用它):
task generateJavaSrcFromFregeSrc {
ant.java(jar:"lib/frege3.21.586-g026e8d7.jar",fork:true) {
arg(value: "-j") // do not run the java compiler
arg(value: "-d")
arg(value: "src/main/java") // the place where to put the generated source code (paired to the -d argument)
arg(value: "src/main/frege/HelloFrege.fr")
}
}
jar {
manifest {
attributes 'Main-Class': 'org.wathever.HelloFrege'
}
}
task fatJar(type: Jar) {
from files(sourceSets.main.output.classesDir)
from files(sourceSets.main.output.resourcesDir)
//from {configurations.compile.collect {zipTree(it)}} // this does not include the autogenerated source code
baseName = project.name + '-fatJar'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
jar
代码块中指定清单详细信息,如果我在task fatJar
中指定它们,那么在运行jar时我会no main manifest attribute, in [...]
。jar
的代码块from("$projectDir") { include 'lib/**'}
来包含Frege jar,那么我会收到类似java.lang.ClassNotFoundException
的错误(我认为因为它包含了Jar)是,而不是一组.class
文件。src/main/java/org/wathever
必须存在(附加信息:Maven约定前缀src/main/java
,后缀为HelloFrege.fr
源代码中指定的“Java包” :module org.wathever.HelloFrege where
)我发现了一些有用的细节: