摆脱 derby.log
Posted
技术标签:
【中文标题】摆脱 derby.log【英文标题】:Getting rid of derby.log 【发布时间】:2010-11-03 12:14:36 【问题描述】:我正在使用 Apache Derby 嵌入式数据库在 Maven 项目中进行单元测试。不幸的是,每当我运行测试时,我都会在项目的根目录中找到derby.log
文件。数据库本身是在target
目录(jdbc:derby:target/unittest-db;create=true
)中创建的,所以这不是问题。在咨询了reference guide 之后,我尝试在JDBC url (jdbc:derby:target/unittest-db;create=true;logDevice=/mylogs
) 上设置logDevice
参数,但这似乎是针对不同的日志,因此derby.log
仍然出现。
非常感谢任何帮助。
【问题讨论】:
【参考方案1】:Derby 允许您使用 Java 系统属性 derby.stream.error.file
指定写入错误日志消息的文件的名称。默认值为“derby.log”。
为了在 Maven 万无一失的测试阶段摆脱 derby.log
,我只是在插件配置中添加属性定义如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<property>
<name>derby.stream.error.file</name>
<value>target/derby.log</value>
</property>
</systemProperties>
</configuration>
</plugin>
【讨论】:
你应该在 target/ 前面加上 $basedir 否则你不能从不同的目录执行 maven。 这非常适用于单元测试,但通常不会产生您想要的集成测试。原因是数据库通常在服务器(例如码头)中,它不会从surefire/failsafe继承环境。 您应该考虑使用 $project.build.directory 变量而不是硬编码目标文件夹。您可以通过创建以下类来摆脱derby.log
文件
public class DerbyUtil
public static final OutputStream DEV_NULL = new OutputStream()
public void write(int b)
;
并设置 JVM 系统属性 derby.stream.error.field
,例如,使用以下 JVM 命令行参数:
-Dderby.stream.error.field=DerbyUtil.DEV_NULL
Credit to whom it is due.
【讨论】:
如果我通过 Hibernate 使用 Derby 会怎样?我在哪里放置“derby.stream.error.field”行? 在 webapp 中设置系统 props 很痛苦。有什么办法吗? 我不这么认为,但是您可以在 web.xml 或 spring 配置中设置一些东西以在启动时运行并在那里执行。 @bmargulies: System.setProperty("derby.stream.error.field", "DerbyUtil.DEV_NULL"); @JoshuaD 不要忘记捕获 SecurityException,如果已实施 Web 容器以防止 webapps 设置系统属性,那么任何好的 Web 容器都应该防止这种情况发生。【参考方案3】:在您的 derby.properties 文件中包含以下内容:
derby.stream.error.file=/dev/null
(或
derby.stream.error.file=\\Device\\Null
在 Windows 上)
【讨论】:
\\Device\\Null 抛出了 FileNotFoundException,但是使用 NUL 代替了这个技巧。谢谢。【参考方案4】:对于集成测试,情况可能比简单的surefire 属性更棘手。
在maven-failsafe-plugin
中指定属性derby.stream.error.file
将不起作用,因为服务器环境不会从该插件继承(显然使用maven-surefire-plugin
没有区别)。
您需要修改实际的服务器启动插件。以下示例适用于maven-jetty-plugin
:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<systemProperties>
<!-- Get rid of that missplaced derby.log. -->
<systemProperty>
<name>derby.stream.error.file</name>
<value>$project.build.directory/derby.log</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
请注意,出于某种原因,我们使用systemProperty
而不仅仅是property
,就像在万无一失的解决方案中那样。
【讨论】:
对不起,这正是我需要的,这应该是公认的答案:)【参考方案5】:您也可以将 derby home 设置为 target/derby
或 target
via:
System.setProperty("derby.system.home", new File("target/derby").getAbsolutePath());
然后使用 JDBC URL jdbc:derby:unittest-db;create=true
。
然后 derby.log 出现在正确的文件夹中。
【讨论】:
【参考方案6】:如果您无权访问配置,则可以在建立连接之前执行此操作:
System.setProperty("derby.stream.error.field", "MyApp.DEV_NULL");
【讨论】:
这也是我在带有@BeforeClass
注解的注解测试方法中所做的【参考方案7】:
我想出了另一个解决方案。试试这个;它对我有用。我在这里所做的是我更改了 System.stream.error.file 路径并将其设置为我的属性文件下存在的属性之一。只需将以下给定代码添加到您的 applicationContext.xml 文件即可。
<bean id="setDerbyLog" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"><value>java.lang.System</value></property>
<property name="targetMethod"><value>setProperty</value></property>
<property name="arguments">
<list>
<value>derby.stream.error.file</value>
<value>$derby.stream.error.file</value>
</list>
</property>
</bean>
【讨论】:
【参考方案8】:这不是您的derby.log
文件问题的解决方案(许多人已经展示了如何解决),而是一个建议。为什么不使用derby-maven-plugin 进行测试?它将derby.log
文件放在target/derby
下,因此不会留下任何垃圾。
如 my answer here 中所述,您可以通过我编写的 derby-maven-plugin 将 Derby 用作您的数据库,该插件可在 GitHub 和 Maven Central 上使用。
【讨论】:
以上是关于摆脱 derby.log的主要内容,如果未能解决你的问题,请参考以下文章