2

次のように定義されたカスタム関数エイリアスを持つ H2 データベース:

create alias to_date as $$
    java.util.Date toDate(java.lang.String dateString, java.lang.String pattern) {
        try {
          return new java.text.SimpleDateFormat(javaPattern).parse(dateString);
        } catch(java.text.ParseException e) {
          throw new java.lang.RuntimeException(e);
        }
      }
$$;

H2 は次のように初期化されます。

jdbc:h2:mem:testdb;INIT=runscript from 'classpath:create_alias.sql

これはテストで使用され、Jenkins インスタンスで複数のプロジェクトに対して同時に実行されます。このようなテストは、次のエラーで失敗することがあります。

Could not get JDBC Connection; nested exception is org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "javac: file not found: org/h2/dynamic/TO_DATE.java
Usage: javac <options> <source files>
use -help for a list of possible options
"; SQL statement:


create alias to_date as $$
    java.util.Date toDate(java.lang.String dateString, java.lang.String pattern) {
    ....

私の推測では、org.h2.util.SourceCompiler は、その時点で実行されている h2 のインスタンスが 1 つだけであると想定しており、生成された Java ソースを「java.io.tmpdir」に書き込みます。これは、同じアカウントで実行されているすべてのプロセス間で共有されます。 . 次の修正を提案します。

Index: SourceCompiler.java
===================================================================
--- SourceCompiler.java (revision 5086)
+++ SourceCompiler.java (working copy)
@@ -40,7 +40,15 @@
      */
     final HashMap<String, Class<?>> compiled = New.hashMap();

-    private final String compileDir = Utils.getProperty("java.io.tmpdir", ".");
+    private final String compileDir;
+    
+    {
+       // use random folder under java.io.tmpdir so multiple h2 could compile at the same time
+       // without overwriting each other files
+       File tmp = File.createTempFile("h2tmp", ".tmp");
+       tmp.mkdir();
+       compileDir = tmp.getAbsolutePath();
+    }

     static {
         Class<?> clazz;

サポート チケットを開く必要がありますか? または、この問題の回避策はありますか?

4

2 に答える 2

0

javax.tools.JavaCompiler APIを使用し、インメモリJavaFileManagerに独自の実装を提供して、これらの一時ファイルの作成を完全に回避できます。

ところで、Janino は javax.tools.JavaCompiler API もサポートしています。

于 2013-09-12T14:11:26.203 に答える