Surprising .m2/repo issue when path contains spaces, all platforms

144 views
Skip to first unread message

Scott Stark

unread,
Mar 20, 2019, 5:38:29 PM3/20/19
to Quarkus Development mailing list
So in looking into https://github.com/quarkusio/quarkus/issues/1402 which started as possibly windows specific issue turns out to be a problem on all platforms when using quarkus:dev against a local maven repository that has a space in the repository path. I figured this would have the simple solution of url encoding the Class-Path: we set in the -dev.jar manifest header, but that does not change the behavior. I have tried both full URLEncoder.encode as well as just replacing spaces with %20 and neither approach is working.

I have not run across any language defined behavior for handling of the Class-Path: value and online answers suggest that just using the %20 replacement should work. Could be that the is something else going on with the handling of the path to the quarkus-core.jar containing the DevModeMain, 

I did find a special _JAVA_LAUNCHER_DEBUG env variable to turn on tracing of the jvm launcher that shows the failure is happening very early on, but I have not located exactly where the manifest Class-Path: is processed into URLs.

```bash

Scotts-iMacPro:getting-started starksm$ mvn compile quarkus:dev

----_JAVA_LAUNCHER_DEBUG----

Launcher state:

debug:on

javargs:off

program name:java

launcher name:java

javaw:off

fullversion:1.8.0_172-b11

dotversion:1.8

ergo_policy:DEFAULT_ERGONOMICS_POLICY

Command line args:

argv[0] = /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/java

argv[1] = -classpath

argv[2] = /usr/local/Cellar/maven/3.6.0/libexec/boot/plexus-classworlds-2.5.2.jar

argv[3] = -Dclassworlds.conf=/usr/local/Cellar/maven/3.6.0/libexec/bin/m2.conf

argv[4] = -Dmaven.home=/usr/local/Cellar/maven/3.6.0/libexec

argv[5] = -Dlibrary.jansi.path=/usr/local/Cellar/maven/3.6.0/libexec/lib/jansi-native

argv[6] = -Dmaven.multiModuleProjectDirectory=/tmp/getting-started

argv[7] = org.codehaus.plexus.classworlds.launcher.Launcher

argv[8] = compile

argv[9] = quarkus:dev

JRE path is /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre

jvm.cfg[0] = ->-server<-

jvm.cfg[1] = ->-client<-

48 micro seconds to parse jvm.cfg

Default VM: server

Does `/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/server/libjvm.dylib' exist ... yes.

----_JAVA_LAUNCHER_DEBUG----

Launcher state:

debug:on

javargs:off

program name:java

launcher name:java

javaw:off

fullversion:1.8.0_172-b11

dotversion:1.8

ergo_policy:DEFAULT_ERGONOMICS_POLICY

Command line args:

argv[0] = /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/java

argv[1] = -classpath

argv[2] = /usr/local/Cellar/maven/3.6.0/libexec/boot/plexus-classworlds-2.5.2.jar

argv[3] = -Dclassworlds.conf=/usr/local/Cellar/maven/3.6.0/libexec/bin/m2.conf

argv[4] = -Dmaven.home=/usr/local/Cellar/maven/3.6.0/libexec

argv[5] = -Dlibrary.jansi.path=/usr/local/Cellar/maven/3.6.0/libexec/lib/jansi-native

argv[6] = -Dmaven.multiModuleProjectDirectory=/tmp/getting-started

argv[7] = org.codehaus.plexus.classworlds.launcher.Launcher

argv[8] = compile

argv[9] = quarkus:dev

JRE path is /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre

jvm.cfg[0] = ->-server<-

jvm.cfg[1] = ->-client<-

42 micro seconds to parse jvm.cfg

Default VM: server

Does `/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/server/libjvm.dylib' exist ... yes.

JVM path is /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/server/libjvm.dylib

2156 micro seconds to LoadJavaVM

JavaVM args:

    version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 10

    option[ 0] = '-Dsun.java.launcher.diag=true'

    option[ 1] = '-Dsun.java.launcher.diag=true'

    option[ 2] = '-Djava.class.path=.'

    option[ 3] = '-Djava.class.path=/usr/local/Cellar/maven/3.6.0/libexec/boot/plexus-classworlds-2.5.2.jar'

    option[ 4] = '-Dclassworlds.conf=/usr/local/Cellar/maven/3.6.0/libexec/bin/m2.conf'

    option[ 5] = '-Dmaven.home=/usr/local/Cellar/maven/3.6.0/libexec'

    option[ 6] = '-Dlibrary.jansi.path=/usr/local/Cellar/maven/3.6.0/libexec/lib/jansi-native'

    option[ 7] = '-Dmaven.multiModuleProjectDirectory=/tmp/getting-started'

    option[ 8] = '-Dsun.java.command=org.codehaus.plexus.classworlds.launcher.Launcher compile quarkus:dev'

    option[ 9] = '-Dsun.java.launcher=SUN_STANDARD'

51564 micro seconds to InitializeJVM

Main class is 'org.codehaus.plexus.classworlds.launcher.Launcher'

App's argc is 2

    argv[ 0] = 'compile'

    argv[ 1] = 'quarkus:dev'

19090 micro seconds to load main class

----_JAVA_LAUNCHER_DEBUG----

[INFO] Scanning for projects...

[INFO] 

[INFO] ----------------------< org.acme:getting-started >----------------------

[INFO] Building getting-started 1.0-SNAPSHOT

[INFO] --------------------------------[ jar ]---------------------------------

[INFO] 

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started ---

[INFO] Using 'UTF-8' encoding to copy filtered resources.

[INFO] Copying 2 resources

[INFO] 

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ getting-started ---

[INFO] Nothing to compile - all classes are up to date

[INFO] 

[INFO] --- quarkus-maven-plugin:999-SNAPSHOT:dev (default-cli) @ getting-started ---

[INFO] Using javaTool: /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/bin/java

[INFO] Using servlet resources /private/tmp/getting-started/src/main/resources/META-INF/resources

----_JAVA_LAUNCHER_DEBUG----

Launcher state:

debug:on

javargs:off

program name:java

launcher name:java

javaw:off

fullversion:1.8.0_172-b11

dotversion:1.8

ergo_policy:DEFAULT_ERGONOMICS_POLICY

Command line args:

argv[0] = /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/bin/java

argv[1] = -Xdebug

argv[2] = -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

argv[3] = -Dquarkus-internal.devMode

argv[4] = -Dquarkus.undertow.resources=/private/tmp/getting-started/src/main/resources/META-INF/resources

argv[5] = -XX:TieredStopAtLevel=1

argv[6] = -Xverify:none

argv[7] = -Djava.util.logging.manager=org.jboss.logmanager.LogManager

argv[8] = -Dquarkus-internal.runner.classes=/private/tmp/getting-started/target/classes

argv[9] = -Dquarkus-internal.runner.sources=/private/tmp/getting-started/src/main/java

argv[10] = -Dquarkus-internal.runner.resources=/private/tmp/getting-started/src/main/resources

argv[11] = -jar

argv[12] = /private/tmp/getting-started/target/getting-started-dev.jar

argv[13] = /private/tmp/getting-started/target/classes

argv[14] = /private/tmp/getting-started/target/wiring-devmode

argv[15] = /private/tmp/getting-started/target/transformer-cache

jvm.cfg[0] = ->-server<-

jvm.cfg[1] = ->-client<-

43 micro seconds to parse jvm.cfg

Default VM: server

Does `/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/server/libjvm.dylib' exist ... yes.

----_JAVA_LAUNCHER_DEBUG----

Launcher state:

debug:on

javargs:off

program name:java

launcher name:java

javaw:off

fullversion:1.8.0_172-b11

dotversion:1.8

ergo_policy:DEFAULT_ERGONOMICS_POLICY

Command line args:

argv[0] = /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/bin/java

argv[1] = -Xdebug

argv[2] = -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

argv[3] = -Dquarkus-internal.devMode

argv[4] = -Dquarkus.undertow.resources=/private/tmp/getting-started/src/main/resources/META-INF/resources

argv[5] = -XX:TieredStopAtLevel=1

argv[6] = -Xverify:none

argv[7] = -Djava.util.logging.manager=org.jboss.logmanager.LogManager

argv[8] = -Dquarkus-internal.runner.classes=/private/tmp/getting-started/target/classes

argv[9] = -Dquarkus-internal.runner.sources=/private/tmp/getting-started/src/main/java

argv[10] = -Dquarkus-internal.runner.resources=/private/tmp/getting-started/src/main/resources

argv[11] = -jar

argv[12] = /private/tmp/getting-started/target/getting-started-dev.jar

argv[13] = /private/tmp/getting-started/target/classes

argv[14] = /private/tmp/getting-started/target/wiring-devmode

argv[15] = /private/tmp/getting-started/target/transformer-cache

jvm.cfg[0] = ->-server<-

jvm.cfg[1] = ->-client<-

52 micro seconds to parse jvm.cfg

Default VM: server

Does `/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/server/libjvm.dylib' exist ... yes.

JVM path is /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/server/libjvm.dylib

2397 micro seconds to LoadJavaVM

JavaVM args:

    version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 16

    option[ 0] = '-Dsun.java.launcher.diag=true'

    option[ 1] = '-Dsun.java.launcher.diag=true'

    option[ 2] = '-Djava.class.path=.'

    option[ 3] = '-Xdebug'

    option[ 4] = '-Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n'

    option[ 5] = '-Dquarkus-internal.devMode'

    option[ 6] = '-Dquarkus.undertow.resources=/private/tmp/getting-started/src/main/resources/META-INF/resources'

    option[ 7] = '-XX:TieredStopAtLevel=1'

    option[ 8] = '-Xverify:none'

    option[ 9] = '-Djava.util.logging.manager=org.jboss.logmanager.LogManager'

    option[10] = '-Dquarkus-internal.runner.classes=/private/tmp/getting-started/target/classes'

    option[11] = '-Dquarkus-internal.runner.sources=/private/tmp/getting-started/src/main/java'

    option[12] = '-Dquarkus-internal.runner.resources=/private/tmp/getting-started/src/main/resources'

    option[13] = '-Djava.class.path=/private/tmp/getting-started/target/getting-started-dev.jar'

    option[14] = '-Dsun.java.command=/private/tmp/getting-started/target/getting-started-dev.jar /private/tmp/getting-started/target/classes /private/tmp/getting-started/target/wiring-devmode /private/tmp/getting-started/target/transformer-cache'

    option[15] = '-Dsun.java.launcher=SUN_STANDARD'

Listening for transport dt_socket at address: 5005

56542 micro seconds to InitializeJVM

JAR file is '/private/tmp/getting-started/target/getting-started-dev.jar'

App's argc is 3

    argv[ 0] = '/private/tmp/getting-started/target/classes'

    argv[ 1] = '/private/tmp/getting-started/target/wiring-devmode'

    argv[ 2] = '/private/tmp/getting-started/target/transformer-cache'

Error: Could not find or load main class io.quarkus.dev.DevModeMain

java.lang.ClassNotFoundException: io.quarkus.dev.DevModeMain

at java.net.URLClassLoader.findClass(URLClassLoader.java:381)

at java.lang.ClassLoader.loadClass(ClassLoader.java:424)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)

at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time:  1.677 s

[INFO] Finished at: 2019-03-20T14:23:11-07:00

[INFO] ------------------------------------------------------------------------

```

Scott Stark

unread,
Mar 20, 2019, 10:12:26 PM3/20/19
to Quarkus Development mailing list
So the issue was not the encoding of the of urls in the manifest, that was actually already being done by converting from a File to a URI. The problem was that the inclusion of the DevModeMain was done by locating the path to the containing jar/file using a class path resource lookup, and then added to the manifest classpath using a file path that was already url encoded, so it ended up being doubly encoded where a space was transformed to %2520 rather than just %20. I have a fix that is working on all platforms.

David Lloyd

unread,
Mar 27, 2019, 11:24:02 AM3/27/19
to Scott Stark, Quarkus Development mailing list
I've written a note about class path URI handling, so if anyone is
going to be doing *anything* with class path URIs now or in the
future, please read this first:
https://github.com/quarkusio/quarkus/issues/1673#issuecomment-477205320
> --
> You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
> Visit this group at https://groups.google.com/group/quarkus-dev.
> For more options, visit https://groups.google.com/d/optout.



--
- DML

Rostislav Svoboda

unread,
Mar 27, 2019, 1:21:58 PM3/27/19
to David M. Lloyd, Scott Stark, Quarkus Development mailing list
We should include those points into our docs.
So-far there is no developers guide, so an entry to extension-authors-guide.adoc ?

David Lloyd

unread,
Mar 27, 2019, 1:32:21 PM3/27/19
to Rostislav Svoboda, Scott Stark, Quarkus Development mailing list
Well... if we follow this to its logical conclusion, there's a point
where the docs cease to be about Quarkus and start to be about general
Internet software engineering in Java. There's a ton of common-sense
stuff we could go on about: how to use Unicode, dates and time zones,
locale handing, IP address handling, how backpressure should work,
security as a general topic, etc. I don't really know where we'd stop
if we started down this path. I consider "reading and understanding
specs" to be well within this "common sense" category, and that
includes URI handling; I only mentioned it specifically because it
seems to be an area that we are consistently making "noisy" mistakes
in.
--
- DML

Rostislav Svoboda

unread,
Mar 27, 2019, 2:30:41 PM3/27/19
to David M. Lloyd, Scott Stark, Quarkus Development mailing list

> On 27 Mar 2019, at 18:31, David Lloyd <david...@redhat.com> wrote:
>
> Well... if we follow this to its logical conclusion, there's a point
> where the docs cease to be about Quarkus and start to be about general

I admit docs are not great place, maybe blog post one day :)

> Internet software engineering in Java. There's a ton of common-sense
> stuff we could go on about: how to use Unicode, dates and time zones,
> locale handing, IP address handling, how backpressure should work,
> security as a general topic, etc. I don't really know where we'd stop
> if we started down this path. I consider "reading and understanding
> specs" to be well within this "common sense" category, and that
> includes URI handling; I only mentioned it specifically because it
> seems to be an area that we are consistently making "noisy” mistakes

Those mistakes are recurring too

We had similar issues with WF/EAP, I bet other projects and products have similar experience
Reply all
Reply to author
Forward
0 new messages