来自the Grails documentation和this问题:
对于常规配置,Grails提供了两个文件:
- 的grails-app / CONF / BuildConfig.groovy
- 的grails-app / CONF / Config.groovy中
醇>他们都使用Groovy的ConfigSlurper语法。第一个是BuildConfig.groovy,用于运行Grails命令时使用的设置,例如compile,doc等。第二个文件Config.groovy用于运行应用程序时使用的设置。这意味着Config.groovy与您的应用程序一起打包,但BuildConfig.groovy不是。
这是关于log4j
框架的摘录:
Grails使用其通用配置机制为底层Log4j日志系统提供设置,因此您所要做的就是将log4j设置添加到文件grails-app / conf / Config.groovy
我有一个包含这两个文件的项目:grails-app/conf/BuildConfig.groovy
和grails-app/conf/Config.groovy
。该项目使用log4j
实用程序,因此某些设置(包括函数)放在 Config.groovy 文件中。现在,根据我引用的文档,它是正确的文件,因为我想使用日志实用程序来运行应用程序,而不是编译它。
有趣的是,当我在项目上运行mvn package
时,会使用这些设置 - 执行log4j
设置中的功能。
根据the documentation和the question,情况并非如此。
我知道可以使用grailsApplication
来访问这些设置:
def recipient = grailsApplication.config.foo.bar.hello
所以我搜索了我的项目并发现了grailsApplication
的一些用法,但没有与log4j设置有关。
在mvn package
期间使用 Config.groovy 文件中放置log4j设置的其他可能原因是什么?我错过了什么?
更新:当我第一次使用mvn package
构建项目时,上述配置似乎有效。下次运行mvn package
时,将使用log4j
文件中的Config.groovy
配置。如果我删除了工作空间,它又能很好地工作。
答案 0 :(得分:3)
有一件重要的事情值得一提。尽管应用程序在运行时使用了Config.groovy
,但它必须首先编译为Java Config.class
。打包应用程序时,编译器必须访问此文件并将其编译为字节码。看一下我下面粘贴的列表,它来自我工作区中的一个Grails应用程序:
ls -l target/classes | awk '{print $8}'
application.properties
BootStrap.class
BootStrap$_closure1.class
BootStrap$_closure2.class
BuildConfig.class
BuildConfig$_run_closure1.class
BuildConfig$_run_closure1_closure2.class
BuildConfig$_run_closure1_closure3.class
BuildConfig$_run_closure1_closure4.class
BuildConfig$_run_closure1_closure5.class
com
Config.class
Config$_run_closure1.class
Config$_run_closure1_closure4.class
Config$_run_closure1_closure4_closure5.class
Config$_run_closure1_closure4_closure5_closure6.class
Config$_run_closure2.class
Config$_run_closure2_closure7.class
Config$_run_closure2_closure8.class
Config$_run_closure3.class
DataSource.class
DataSource$_run_closure1.class
DataSource$_run_closure2.class
DataSource$_run_closure3.class
DataSource$_run_closure3_closure4.class
DataSource$_run_closure3_closure4_closure7.class
DataSource$_run_closure3_closure5.class
DataSource$_run_closure3_closure5_closure8.class
DataSource$_run_closure3_closure6.class
DataSource$_run_closure3_closure6_closure9.class
DataSource$_run_closure3_closure6_closure9_closure10.class
resources.class
resources$_run_closure1.class
UrlMappings.class
UrlMappings$__clinit__closure1.class
UrlMappings$__clinit__closure1_closure2.class
UrlMappings$__clinit__closure1_closure2_closure3.class
您可以看到Config.groovy
文件已编译为Config.class
文件,并且Config.groovy
内使用的所有闭包都被编译为Java的匿名类(例如{{1} })。这就是为什么如果你把一些执行任何逻辑的代码放到Config$_run_closure1_closure4.class
你必须预期它将被编译和执行,因为编译的类扩展Config.groovy
并且它执行Groovy脚本文件的主体。您可以在下面找到groovy.lang.Script
文件的外观:
Groovy.class
javap -l target/classes/Config.class
现在要了解执行Compiled from "Config.groovy"
public class Config extends groovy.lang.Script {
public static transient boolean __$stMC;
public static long __timeStamp;
public static long __timeStamp__239_neverHappen1501076781354;
public Config();
LocalVariableTable:
Start Length Slot Name Signature
4 4 0 this LConfig;
public Config(groovy.lang.Binding);
LocalVariableTable:
Start Length Slot Name Signature
4 21 0 this LConfig;
4 21 1 context Lgroovy/lang/Binding;
public static void main(java.lang.String...);
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 args [Ljava/lang/String;
public java.lang.Object run();
LineNumberTable:
line 14: 4
line 17: 43
line 18: 126
line 24: 194
line 26: 233
line 30: 296
line 31: 323
line 38: 376
line 42: 419
line 45: 453
line 63: 473
line 65: 507
line 68: 550
line 70: 595
line 72: 631
line 74: 679
line 77: 724
line 80: 777
line 84: 822
line 86: 867
line 88: 912
line 99: 932
LocalVariableTable:
Start Length Slot Name Signature
0 964 0 this LConfig;
public java.lang.Object this$dist$invoke$3(java.lang.String, java.lang.Object);
LocalVariableTable:
Start Length Slot Name Signature
0 68 0 this LConfig;
0 68 1 name Ljava/lang/String;
0 68 2 args Ljava/lang/Object;
public void this$dist$set$3(java.lang.String, java.lang.Object);
LocalVariableTable:
Start Length Slot Name Signature
0 53 0 this LConfig;
0 53 1 name Ljava/lang/String;
0 53 2 value Ljava/lang/Object;
public java.lang.Object this$dist$get$3(java.lang.String);
LocalVariableTable:
Start Length Slot Name Signature
0 46 0 this LConfig;
0 46 1 name Ljava/lang/String;
protected groovy.lang.MetaClass $getStaticMetaClass();
public static void __$swapInit();
static {};
public int super$1$hashCode();
public void super$3$printf(java.lang.String, java.lang.Object);
public void super$3$printf(java.lang.String, java.lang.Object[]);
public void super$3$setProperty(java.lang.String, java.lang.Object);
public boolean super$1$equals(java.lang.Object);
public void super$1$finalize();
public groovy.lang.Binding super$3$getBinding();
public void super$3$print(java.lang.Object);
public void super$3$setBinding(groovy.lang.Binding);
public java.lang.Object super$3$evaluate(java.io.File);
public java.lang.String super$1$toString();
public java.lang.Object super$3$evaluate(java.lang.String);
public void super$2$setMetaClass(groovy.lang.MetaClass);
public void super$1$notify();
public java.lang.Object super$3$invokeMethod(java.lang.String, java.lang.Object);
public java.lang.Object super$1$clone();
public void super$1$wait(long, int);
public void super$1$wait(long);
public void super$1$wait();
public groovy.lang.MetaClass super$2$getMetaClass();
public java.lang.Class super$1$getClass();
public void super$3$run(java.io.File, java.lang.String[]);
public void super$3$println(java.lang.Object);
public void super$1$notifyAll();
public java.lang.Object super$3$getProperty(java.lang.String);
public void super$3$println();
static java.lang.Class class$(java.lang.String);
}
的原因,我们需要深入了解Config.groovy
执行时会发生什么。运行grails package
命令会使grails-core中的grails package
脚本被执行。 _GrailsPackage.groovy
目标调用packageApp
此方法调用GrailsProjectPackager.packageApplication()
助手类:
在createConfig()
方法实现中,我们可以找到createConfig()
执行:
这是一个Groovy类,它解析脚本,最后在解析的脚本上调用ConfigSlurper.parse(script)
。使用调试器很容易找到 - 在我的视频中查看我在这个特定示例中如何执行此操作:https://www.youtube.com/watch?v=s2PN6TjFjUI
我希望它有所帮助。
答案 1 :(得分:1)
mvn package
将运行其他maven阶段,其中包括test
阶段。 Grails集成测试将引导您的完整应用程序,以便解析Config.groovy文件。