microsoft / vscode-java-test

Run and debug Java test cases in Visual Studio Code.
https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-test
Other
294 stars 127 forks source link

Cannot run tests when the path has space #1197

Open Empressia opened 3 years ago

Empressia commented 3 years ago

環境

問題

JPMSの(module-info.javaを含む)テストを実行しようとすると、
TestEngineを探しに行くときにネットワークパスを探しに行ってエラーとなります。

java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: Error locating configuration files

module-info.javaを削除してRun Testを実行すると正常にテストが実施されます。

gradleからは正常にテストが実施されます。

参考

以下に、サンプルのプロジェクトを作成しました。
https://github.com/Empressia/VSCodeJavaTest02

jdneo commented 3 years ago

@Empressia thank you for reporting the issue. Would you mind to update it to English?

Empressia commented 3 years ago

I tried to translate.

Environment

Problem

Try to run a test that contains "module-info.java"(JPMS file), TestEngine not found.
It seems to access the network path.

java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: Error locating configuration files

Remove "module-info.java" and Run Test, the test will run successfully.

The test is successful with gralde.

Reference

I created a sample project.
https://github.com/Empressia/VSCodeJavaTest02

jdneo commented 3 years ago

Thank you @Empressia, will take a look

jdneo commented 3 years ago

@Empressia Please correct me if I'm wrong.

The sample project looks very similar with that in https://github.com/microsoft/vscode-java-test/issues/1101.

So I guess once the user can set modulePaths in the test configuration, the problem should be resolved?

Empressia commented 3 years ago

"modulePaths"を設定できると、それは解決できるかもれません。

ただそれは、"module-info.java"の違いから考えられる、テストへの入力の違いだからです。
現在得られているエラー出力からではありません。

よって、可能性があるとは思いますが、それ以上のことはわかりません。


If I can set "modulePaths", it may be solved.

That's because I think the input to the test is different depending on the "module-info.java".
Not from the error output currently obtained.

So I think there's a possibility of a fix with "modulePaths", but I don't know more than that.

Empressia commented 3 years ago

否定する要素としては、このプロジェクトでは、外部のモジュールを使用していないため、
module pathを明示的に指定する必要がなさそうなことです。


From a negable point of view, this project doesn't use external modules, so i don't seem to have to explicitly specify module path.

jdneo commented 2 years ago

We planed to add modulePath field in the test configuration in the next release. Since this issue looks similar to #1101, I'm closing this one and use #1101 to track the request.

Thanks for reporting.

Empressia commented 2 years ago

1101 は対応いただきました。ありがとうございます。そちらは解決しました。

しかし、こちらは、依然、問題が継続しています。

確認をお願いできますか?

なお、確認したバージョンは以下の通りです。


1101 was supported. thank you. That's solved.

However, this problem continues.

Can you check it out?

The confirmed version is as follows.


Environment

jdneo commented 2 years ago

What's the version of Language Support for Java extension on your side?

The sample project https://github.com/Empressia/VSCodeJavaTest02 works on my side without any additional settings: image

Empressia commented 2 years ago

↓ click『▷』. スクリーンショット 2021-12-24 110707

↓ run test using gradle. スクリーンショット 2021-12-24 110930

jdneo commented 2 years ago

Looks like a issue related to the file system.

Have you tried it in Eclipse?

Empressia commented 2 years ago

Looks like a issue related to the file system.

ヒントをありがとうございます。 Thank you for the tips.

スペースのないディレクトリパスに移動したら、成功しました(~/Visual Studio Code/VSCodeJaaTest02→~/Temporary/VSCodeJaaTest02)。 I moved to a directory path with no space and it ended successfully.

スペースのあるディレクトリパスでも動くようにしてもらえるものでしょうか? Can you make sure that directory paths with spaces work?

jdneo commented 2 years ago

Yes I can repro this issue but have no idea why.

The debug console says:

...
    at java.base/java.lang.Class.newInstance(Class.java:584)
Class.java:584
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createRawTestLoader(RemoteTestRunner.java:371)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createLoader(RemoteTestRunner.java:366)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.defaultInit(RemoteTestRunner.java:310)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.init(RemoteTestRunner.java:225)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.nio.file.FileSystemException: \\VSCodeJavaTest02 master\bin\default\META-INF\services\org.junit.platform.engine.TestEngine: The filename, directory name, or volume label syntax is incorrect.

But I didn't see any occurrence of the string META-INF in the resolved launch configuration

Empressia commented 2 years ago

わたしの想像ですが……。 It's my idea...

スタックトレースとJUnitのドキュメントから、JUnitではServiceLoaderを使用して設定を読み込んでいると思います。 From the stack trace and JUnit documentation, I think JUnit uses ServiceLoader to load the settings.

https://junit.org/junit5/docs/5.7.0/api/org.junit.platform.launcher/org/junit/platform/launcher/core/LauncherFactory.html

そのパスの一部が、上記URLにあります。 Part of the path can be found at the url above.

By default, test engines are discovered at runtime using the ServiceLoader mechanism. For that purpose, a text file named META-INF/services/org.junit.platform.engine.TestEngine has to be added to the engine's JAR file in which the fully qualified name of the implementation class of the TestEngine interface is declared.

その設定をクラスパス上で検索している間に、『\\ProjectDirectoryName』形式のネットワークパスを参照してしまっている……ということでしょう。 While searching for that setting on the classpath, it refers to the network path in the form of "\\ProjectDirectoryName".

あとは、テストの起動時に、どのようなパスが渡っているのかが問題だと思うのですが、 テストを実行するときの具体的なパラメーター(『\』や『"』の有無を含む)を確認することはできますか? Also, I think the problem is what kind of path is passing when the test starts. Can you check the specific parameters (including the presence or absence of 『"』 or 『\』) when running the test?

jdneo commented 2 years ago

Thank you for the information. I added a breakpoint at

https://github.com/microsoft/vscode-java-test/blob/78717ac77a2168372d6109d6fad82ad439e93900/src/controller/testController.ts#L229

And below is the configuration that test runner will pass to the debugger

{
  name: "Launch Java Tests - Test02Tests",
  type: "java",
  request: "launch",
  mainClass: "org.eclipse.jdt.internal.junit.runner.RemoteTestRunner",
  projectName: "VSCodeJavaTest02 master",
  cwd: "C:\\Users\\<user_name>\\Downloads\\VSCodeJavaTest02 master",
  classPaths: [
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.junit.platform\\junit-platform-commons\\1.7.0\\84e309fbf21d857aac079a3c1fffd84284e1114d\\junit-platform-commons-1.7.0.jar",
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.junit.jupiter\\junit-jupiter-api\\5.7.0\\b25f3815c4c1860a73041e733a14a0379d00c4d5\\junit-jupiter-api-5.7.0.jar",
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.hamcrest\\hamcrest\\2.2\\1820c0968dba3a11a1b30669bb1f01978a91dedc\\hamcrest-2.2.jar",
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.apiguardian\\apiguardian-api\\1.1.0\\fc9dff4bb36d627bdc553de77e1f17efd790876c\\apiguardian-api-1.1.0.jar",
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.opentest4j\\opentest4j\\1.2.0\\28c11eb91f9b6d8e200631d46e20a7f407f2a046\\opentest4j-1.2.0.jar",
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.junit.platform\\junit-platform-engine\\1.7.0\\eadb73c5074a4ac71061defd00fc176152a4d12c\\junit-platform-engine-1.7.0.jar",
    "C:\\Users\\<user_name>\\.gradle\\caches\\modules-2\\files-2.1\\org.junit.jupiter\\junit-jupiter-engine\\5.7.0\\d9044d6b45e2232ddd53fa56c15333e43d1749fd\\junit-jupiter-engine-5.7.0.jar",
    "C:\\Users\\<user_name>\\.vscode\\extensions\\redhat.java-1.2.0\\server\\config_win\\org.eclipse.osgi\\78\\0\\.cp",
    "C:\\Users\\<user_name>\\.vscode\\extensions\\redhat.java-1.2.0\\server\\config_win\\org.eclipse.osgi\\47\\0\\.cp",
    "C:\\Users\\<user_name>\\.vscode\\extensions\\redhat.java-1.2.0\\server\\config_win\\org.eclipse.osgi\\87\\0\\.cp",
  ],
  modulePaths: [
    "C:\\Users\\<user_name>\\Downloads\\VSCodeJavaTest02 master\\bin\\main",
  ],
  args: [
    "-version",
    "3",
    "-port",
    "51982",
    "-testLoaderClass",
    "org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader",
    "-loaderpluginname",
    "org.eclipse.jdt.junit5.runtime",
    "-testNameFile",
    "C:\\Users\\<user_name>\\AppData\\Local\\Temp\\testNames4035275782057965145.txt",
  ],
  vmArgs: [
    "-ea",
    "--add-opens",
    "jp.empressia.vscode_java_test/jp.empressia.vscode_java_test_01=ALL-UNNAMED",
    "--add-modules=ALL-MODULE-PATH",
    "--patch-module",
    "jp.empressia.vscode_java_test=C:\\Users\\<user_name>\\Downloads\\VSCodeJavaTest02 master\\bin\\test;\\VSCodeJavaTest02 master\\bin\\default",
    "--add-reads",
    "jp.empressia.vscode_java_test=ALL-UNNAMED",
  ],
  env: undefined,
  envFile: undefined,
  noDebug: true,
  sourcePaths: undefined,
  preLaunchTask: undefined,
  __progressId: "6e0a88bd-3a2d-458c-988c-12af44db95da",
  console: "internalConsole",
}

But so far I haven't did into the org.eclipse.jdt.internal.junit.runner.RemoteTestRunner. Looks like the error is happened when dealing with org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader

BTW, if you have any insight of this, feel free to share, thanks!

Empressia commented 2 years ago

情報ありがとうございます。 Thank you for the information.

vmArgs引数の"--patch-module"のあとに、『~;\\VSCodeJavaTest02 master\\bin\\default"』が含まれているのが問題に見えますがどうでしょうか。 For vmArgs arguments, what about the problem is that the arguments after "--patch-module" contain 『~;\\VSCodeJavaTest02 master\\bin\\default"』?