-
Notifications
You must be signed in to change notification settings - Fork 1.1k
broken support for use of wildcards in the compiler classpath on Windows #10761
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
|
I've just tried it on linux and |
FWIW, the code that deals with |
The problem does seem to be specific to Windows, no such problem in Linux. I will investigate further this afternoon. scalac -classpath 'c:/opt/uejlib2.13/*' /opt/ue/jsrc/s3.sc The invocation in Windows that I provided above is basically the java command that resulted when I issued the same command from a cygwin session, so it's possible that the "scalac" bash script behaves incorrectly in Windows. Is there a plan to provide Windows batch files? To be clear, I'm not advocating the need for scalac.bat, etc., but am curious. |
I don't think the script is the source of the problem, the problem is we pass wildcards to java.nio.file.Paths.get which happens to work on Linux but not Windows. |
When I reduce the code in val cp = "/opt/uejlib2.13/*"
val url = java.nio.file.Paths.get(cp).toUri.toURL
println(url) I get different behavior in Windows versus Linux: Windows:
Linux:
So java.nio.file.Path treats a wildcard entry differently in Windows. This seems to explain why: https://stackoverflow.com/questions/27522581/asterisks-in-java-path The short version: asterisk is a legal filename character in Linux, but not in Windows. I will investigate using the |
FYI, the compiler doesn't currenty permit source files to be on a drive other than the current session drive. My /tmp directory is mounted to G: (a disk drive) to avoid wearing out my SSD drive.
Output (click arrow to expand)exception occurred while compiling G:\tmp\s3.sc java.lang.IllegalArgumentException: 'other' has different root while compiling G:/tmp/s3.sc
Exception in thread "main" java.lang.IllegalArgumentException: 'other' has different root
at java.base/sun.nio.fs.WindowsPath.relativize(WindowsPath.java:404)
at java.base/sun.nio.fs.WindowsPath.relativize(WindowsPath.java:42)
at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:346)
at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$2(Trees.scala:1369)
at scala.collection.immutable.List.mapConserve(List.scala:472)
at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1369)
at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformStats(Trees.scala:1367)
at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1354)
at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:54)
at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:417)
at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:21)
at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:296)
at scala.collection.immutable.List.map(List.scala:246)
at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:297)
at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:185)
at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
at dotty.tools.dotc.Run.runPhases$5(Run.scala:195)
at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:203)
at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
at dotty.tools.dotc.Run.compileUnits(Run.scala:210)
at dotty.tools.dotc.Run.compileSources(Run.scala:147)
at dotty.tools.dotc.Run.compile(Run.scala:129)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
at dotty.tools.dotc.Driver.process(Driver.scala:193)
at dotty.tools.dotc.Driver.process(Driver.scala:162)
at dotty.tools.dotc.Driver.process(Driver.scala:174)
at dotty.tools.dotc.Driver.main(Driver.scala:201)
at dotty.tools.dotc.Main.main(Main.scala)
compile error A workaround is to pushd g:/tmp, compile, and then popd. |
@liufengyun wow, good to know! |
@philwalk You may also be interested in my GitHub repo PS. People working with Cygwin Bash or MSYS2 Bash can use the shell script |
@michelou Thanks, that looks like an interesting resource. |
This comment has been minimized.
This comment has been minimized.
A correction to my previous comment: It seems that you can specify the classpath EITHER via -classpath or @argsfile, but not both. Perhaps the one that appears later on the command line (? just a guess) supercedes the previous one. In a scripting environment, it would be nice to be able to specify a static @argsfile, but it doesn't appear to be feasible. |
This seems to be partially fixed in the current compiler: Here's my test script, named #!./bin/scala -classpath './ulib/*'
!#
// compile failure unless these imports are resolved via above -classpath
import better.files._
import better.files.Dsl._
@main def m() =
printf("Testing wildcard classpath entries below '%s'.\n",".")
printf("Testing wildcard classpath entries below '%s'.\n",cwd) I prep my test environment like this:
In my Linux environment, the script compiles (imports are resolved), but there's a runtime exception: $ touch ./processTestLinux.sc ; ./processTestLinux.sc
Testing wildcard classpath entries below '.'.
Exception in thread "main" java.lang.NoClassDefFoundError: better/files/Dsl$
at processTestLinux$package$.m(processTestLinux.sc:10)
at m.main(processTestLinux.sc:8)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at dotty.tools.scripting.ScriptingDriver.compileAndRun(ScriptingDriver.scala:39)
at dotty.tools.scripting.Main$.main(Main.scala:39)
at dotty.tools.scripting.Main.main(Main.scala)
Caused by: java.lang.ClassNotFoundException: better.files.Dsl$
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 9 more There is other evidence, but I'll have to get back later. |
@philwalk I assume I should read
|
@michelou - yes, your corrections are valid, I updated my comment. I have a fix for this issue and can create a PR soon, if tests look good. The problem has a couple of facets:
The wildcard entries are already expanded in Windows when I examine them at That solves the original crash symptom:
update on 2021-03-11: does not actually solve the original crash problem for all use-cases, see #11633 comment at line 71 of dist/bin/scala The PR should solve the remaining runtime classpath problems. |
…fix-10761 fix for #10761 ; expand wildcard classpath entries
Minimized code
Output (click arrow to expand)
Use of wildcards in the classpath has been supported by java since java 6. See stack overflow: including-all-the-jars-in-a-directory-within-the-java-classpath
It has also been supported at least since scala 2.8, and is critical for working around OS command line length limitations.
The current implementation assumes that every classpath entry is a file, leading to a compiler crash when the glob entry is encountered.
An alternative way to avoid long classpath problems has been available since java 9+, and is described here (see @raman's entry):
stackoverflow: using an argument file to pass classpath entries
Briefly, it the classpath is specified in a text file (e.g., cparg), which is passed to java like so:
java @c:\path\to\cparg
A similar approach could be implemented in dotty.tools.dotc.Main.main, although ideally it would allow an os-independent format, not requiring the use of path separators (e.g., one classpath entry per line).
The text was updated successfully, but these errors were encountered: