2014-11-03 131 views
1
一个弗雷格项目的罐

我想:建筑用摇篮

  1. 使用弗雷格的编程语言来编写一个简单的“Hello World”的一段代码,
  2. 然后使用弗雷格编译器生成等效的Java源代码,
  3. 然后构建一个可执行的Jar文件从命令行运行,
  4. 所有先前的步骤应该由Gradle“控制”。

我能够生成源代码(上一个列表中的项目1和2),但我不能在输出中指定Java源代码的“包”结构,即我可以没有看到package Java语句作为生成Java源代码中的第一行代码。我可以向Frege编译器指定放置生成代码的位置(通过参数-d)。

我认为这就是为什么当构建一个可执行Jar,然后启动它时,我看到类似的错误(根据对Gradle任务的不同尝试),例如:no main manifest attribute

将Frege源代码保存在名为HelloFrege.fr的文件中,生成的Java源代码位于名为HelloFrege.java的文件中(我验证该文件包含预期的main方法)。

这里还有的摇篮“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 
} 

这里还有的摇篮“罐”任务的另一个版本:

jar { 
    manifest { 
     attributes 'Main-Class': 'HelloFrege' 
    } 
} 

我怎样才能解决这个问题?我想避免手动将包引用添加到自动生成的Java源代码文件。

回答

2

如果您在Frege中的模块名称不合格,例如HelloWorld,您将看不到Java中生成的软件包语句。模块名称将成为类名称,并且包将为空或默认包。

如果您的模块名称是合格的,例如foo.bar.HelloWorld,那么foo.bar将是软件包名称,HelloWorld将是生成的Java源代码中的类名称。

规则是,模块名称的最后部分成为类名称,限定符形成生成的Java源代码包中的名称。

1

我不知道什么gradle这个可以在这方面为你做什么,但没有gradle这个,下面应该至少是可能的:

... build your jar, as before ... 
jar -uvfe project-all.jar HelloFrege 
java -jar project-all.jar # run it 

这,当然,仅仅是另一种方式来创建清单。如果这样做,那么现在就该调查为什么Gradle拒绝这么做了。

Postscriptum:在考虑了一下问题后,我想你可能会认为源文件名/路径与java包名有关。在Frege中并不是这样,尽管让文件路径与包名匹配并且文件基名与类名相匹配是很好的做法(就像在Java中一样)。此外,为了消除一些混淆,请使用模块关键字。正如Marimuthu所解释的那样,Java包和类名是从frege模块名称派生的。

例子:

$ cat Foo.fr 
module my.org.Baz where 
... 
$ java -jar fregec.jar -d bin Foo.fr 

由此,在包my.orgBaz类,并创建bin/my/org/Baz.class

0

类文件,我至今张贴在这里我的发现。这对我的作品摇篮命令的组合是一个(在命令行中键入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然后当运行的罐子我得到no main manifest attribute, in [...]
  • 如果我使用的代码jar只是块与物业from("$projectDir") { include 'lib/**'}以包括弗雷格罐子,然后我得到这样的错误java.lang.ClassNotFoundException(我想是因为被包含的Jar因为它而不是一组.class文件)。
  • src/main/java/org/wathever需要运行摇篮之前赶到那里的文件夹(附加信息:使用Maven约定前缀src/main/java作为后缀为HelloFrege.fr源代码中指定的“Java包”:module org.wathever.HelloFrege where

一些有用的细节我发现:

+0

但是请注意,你不能在一般的使用-j标志。例如,当A依赖于B时,编译器A编译器将需要B的类文件。 – Ingo 2014-11-04 08:08:01