摆脱 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 变量而不是硬编码目标文件夹。 $project.build.directory/derby.log【参考方案2】:

您可以通过创建以下类来摆脱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/derbytargetvia:

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的主要内容,如果未能解决你的问题,请参考以下文章

铁路围栏密码摆脱循环重复[关闭]

我应该摆脱继续声明[关闭]

摆脱 #!在 angularjs ngRoute [重复]

TSLint 摆脱缺失的空白

如何摆脱 PHP 中的 filesize() 警告?

摆脱 UITableView 上方的行