本文介紹了設置H2 init運行腳本時出現問題。使用Java模塊化系統時,如果腳本不在類路徑根文件夾中,則找不到文件的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
以下是有關如何從資源文件夾初始化運行腳本的問題的接受答案:problem with INIT=RUNSCRIPT and relative paths。
連接字符串:
jdbc:h2:mem:;INIT=RUNSCRIPT FROM 'classpath:desktop/core/database/databaseCreation.sql'
但是,我得到異常,即使文件存在,也找不到文件。
異常:
org.h2.jdbc.JdbcSQLNonTransientException: IO Exception: "java.io.FileNotFoundException: resource /desktop/core/database/databaseCreation.sql"; "classpath:desktop/core/database/databaseCreation.sql"; SQL statement:
RUNSCRIPT FROM 'classpath:desktop/core/database/databaseCreation.sql' [90031-210]
at com.h2database@2.1.210/org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
at com.h2database@2.1.210/org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
at com.h2database@2.1.210/org.h2.message.DbException.get(DbException.java:216)
at com.h2database@2.1.210/org.h2.message.DbException.convertIOException(DbException.java:461)
at com.h2database@2.1.210/org.h2.command.dml.ScriptBase.openInput(ScriptBase.java:168)
at com.h2database@2.1.210/org.h2.command.dml.RunScriptCommand.update(RunScriptCommand.java:52)
at com.h2database@2.1.210/org.h2.command.CommandContainer.update(CommandContainer.java:174)
at com.h2database@2.1.210/org.h2.command.Command.executeUpdate(Command.java:252)
at com.h2database@2.1.210/org.h2.engine.Engine.openSession(Engine.java:279)
at com.h2database@2.1.210/org.h2.engine.Engine.createSession(Engine.java:201)
at com.h2database@2.1.210/org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at com.h2database@2.1.210/org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at com.h2database@2.1.210/org.h2.Driver.connect(Driver.java:59)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:252)
at ispfdesktop/desktop.core.database.DatabaseManager.connectToInMemoryDatabase(DatabaseManager.java:184)
at ispfdesktop/desktop.core.database.CRUDTests.setUpBeforeClass(CRUDTests.java:21)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeAllMethod(TimeoutExtension.java:68)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods$9(ClassBasedTestDescriptor.java:384)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:382)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:196)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.io.FileNotFoundException: resource /desktop/core/database/databaseCreation.sql
at com.h2database@2.1.210/org.h2.store.fs.disk.FilePathDisk.newInputStream(FilePathDisk.java:386)
at com.h2database@2.1.210/org.h2.store.fs.FileUtils.newInputStream(FileUtils.java:267)
at com.h2database@2.1.210/org.h2.command.dml.ScriptBase.openInput(ScriptBase.java:166)
... 69 more
嘗試使用getResource(DatabaseManager類位于desktop.core.database包中)訪問文件時會發現文件已存在:
String file = DatabaseManager.class.getResource("databaseCreation.sql").getFile();
boolean yes = new File(file).exists(); // yes is true
已在Windows(10)和Linux(Kubuntu)平臺上試用,并使用2.1.210版的H2。
更新#1
文件在根類路徑文件夾classpath:databaseCreation.sql
中找到,但在某個子文件夾(如桌面/core/數據庫)下仍找不到。
在第一個子文件夾前追加”/”無效。
已嘗試將SQL文件放入所有文件夾。
'classpath:desktop/core/database/databaseCreation.sql'
不起作用
'classpath:desktop/core/databaseCreation.sql'
不起作用
'classpath:desktop/databaseCreation.sql'
不起作用
只有這樣才有效
'classpath:databaseCreation.sql'
不使用類路徑:
在不使用類路徑的情況下,文件可以位于任何子文件夾中,但這樣,我需要使用文件的絕對路徑:
jdbc:h2:mem:;INIT=RUNSCRIPT FROM '<absolute path here>'
將問題保留為打開狀態,因為引用的問題的答案已過期,該答案在當前H2版本上不起作用,并且希望了解如何使用classpath
使其起作用。
更新2
為了進行復制,您需要在項目中使用Java模塊化系統(MODULE-INFO.Java)。
推薦答案
更新:(模塊-info.Java)
根據您的評論,您的原始設置使用的是JDK 9+模塊。這是一個復雜而令人困惑的話題。最簡單的方法就是刪除MODULE-info.Java,而不使用模塊。如果您打算使用模塊并將資源保存在單獨的目錄(模塊)中,則有多個選項,但沒有一個明確的選擇。也許最簡單的選擇是打開包含該資源的";包。在我的本地測試中,類似這樣的內容起作用了:
module myAppModule {
exports desktop.core.database;
opens desktop.core.database;
requires java.sql;
requires org.junit.jupiter.api;
}
更多信息:
https://www.oracle.com/corporate/features/understanding-java-9-modules.html
Loading classes and resources in Java 9
Accessing resource files in a java jigsaw module
How to access resource using class loader in Java 9
Accessing resource files from external modules
原始
我無法使用非常簡單的Maven設置復制您的問題,該設置僅將H2運行時作為依賴項(相同版本,2.1.210)以及JUnit5。它按預期工作。
堆棧跟蹤顯示這是作為一個測試從Eclipse中運行的。如果我手動添加src/main/resources
作為Java構建路徑源文件夾,但不包括**/
,這將排除資源的子目錄,我可以在Eclipse中準確地復制您的問題。
如果您使用的是maven,或許可以嘗試使用mvn test
在命令行上運行,以驗證它不是您的Eclipse安裝程序。
否則,您將需要發布更多信息以獲取幫助。
這篇關于設置H2 init運行腳本時出現問題。使用Java模塊化系統時,如果腳本不在類路徑根文件夾中,則找不到文件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,