[2.0] Running from C:\Program Files

615 views
Skip to first unread message

Marcus Downing

unread,
Apr 28, 2012, 7:53:35 PM4/28/12
to play-fr...@googlegroups.com
I'm disappointed to find that Play! 2.0 still won't run correctly on Windows if the path contains spaces. This prevents it from ever being put in the Program Files directory, resulting in the following error:

C:\Users\Marcus Downing\Documents\Projects\Character Sheets>play
Exception in thread "main" java.lang.NoClassDefFoundError: Files\play-2/0\repository
Caused by: java.lang.ClassNotFoundException: Files\play-2.0\repository
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: Files\play-2.0\repository.  Program will exit.

It's clearly splitting the path into two arguments. Yes, this can be fixed by putting the files at C:\play-2.0\. But Program Files has been the standard, correct place to put software for 17 years now, ever since Windows 95 came out. The days of software needing to be installed directly into C:\ should have been forgotten along with Windows 3.1. I'm sure it's just a matter of correctly quoting the path in a few places in the batch file, so please fix this.

Ideally I'd like an actual installer for Windows (and an ebuild for Gentoo). But that's a much bigger request, which I'll understand resisting.

Kevin Bosman

unread,
Apr 28, 2012, 8:22:11 PM4/28/12
to play-fr...@googlegroups.com
> matter of correctly quoting the path in a few places in the batch file, so
> please fix this.

Please try applying the attached patch to your play.bat, and let me
know if it resolves the problem for you.

If it works, then we can try getting the committers to incorporate it
into the next release...
play.bat.patch

Marcus Downing

unread,
Apr 28, 2012, 8:39:30 PM4/28/12
to play-fr...@googlegroups.com
That's a start but not sufficient. It's now saying:

C:\Users\Marcus Downing\Documents\Projects\Character Sheets\Composer2>play run
java.lang.IllegalArgumentException
        at java.net.URI.create(Unknown Source)
        at java.net.URI.resolve(Unknown Source)
        at xsbt.boot.Configuration$.resolve$1(Configuration.scala:50)
        at xsbt.boot.Configuration$$anonfun$1.apply(Configuration.scala:56)
        at scala.collection.Iterator$$anon$21.hasNext(Iterator.scala:371)
        at xsbt.boot.Configuration$.configurationFromFile(Configuration.scala:57)
        at xsbt.boot.Configuration$.find(Configuration.scala:25)
        at xsbt.boot.Launch$.apply(Launch.scala:14)
        at xsbt.boot.Boot$.runImpl(Boot.scala:25)
        at xsbt.boot.Boot$.main(Boot.scala:15)
        at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.net.URISyntaxException: Illegal character in path at index 18: file:///C:/Program Files/play-2.0/framework/sbt/sbt.boot.properties
        at java.net.URI$Parser.fail(Unknown Source)
        at java.net.URI$Parser.checkChars(Unknown Source)
        at java.net.URI$Parser.parseHierarchical(Unknown Source)
        at java.net.URI$Parser.parse(Unknown Source)
        at java.net.URI.<init>(Unknown Source)
        ... 11 more
Error during sbt execution: java.lang.IllegalArgumentException

Marcus Downing

unread,
Apr 28, 2012, 9:16:33 PM4/28/12
to play-fr...@googlegroups.com
The nadir of the batch script is the Java command:

java -Xms512M -Xmx1024M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M  
  -Dfile.encoding=UTF8 -Dplay.version=""2.0""
  -Dsbt.ivy.home="C:\Program Files\play-2.0\framework\..\repository"
  -Dplay.home="C:\Program Files\play-2.0\framework\."
  -Dsbt.boot.properties="file:///C:/Program Files/play-2.0/framework/sbt/sbt.boot.properties"
  -jar "C:\Program Files\play-2.0\framework\sbt\sbt-launch.jar" run

...which looks correct to me as it's launching sbt-launch.jar. That means the next problem to fix is inside the java/scala part.

It looks like the java.net.URI class doesn't accept spaces, even though the string is being passed in correctly. If you can substitute %20 it should be happier. It looks like SBT is at fault here?

Kevin Bosman

unread,
Apr 28, 2012, 9:16:11 PM4/28/12
to play-fr...@googlegroups.com
> That's a start but not sufficient.

Right. Please try this one then instead. Note that this patches both
play.bat and framework\build.bat
space-paths.patch

Kevin Bosman

unread,
Apr 28, 2012, 9:18:13 PM4/28/12
to play-fr...@googlegroups.com
> It looks like the java.net.URI class doesn't accept spaces, even though the
> string is being passed in correctly. If you can substitute %20 it should be
> happier.

Exactly. The last patch does exactly that. :)

Marcus Downing

unread,
Apr 28, 2012, 9:29:26 PM4/28/12
to play-fr...@googlegroups.com
Clever. I've never seen a batch script do character replacement before.

Here's the resulting Java command:

java -Xms512M -Xmx1024M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M  
  -Dfile.encoding=UTF8 -Dplay.version=""2.0"" 
  -Dsbt.ivy.home="C:\Program Files\play-2.0\framework\..\repository" 
  -Dplay.home="C:\Program Files\play-2.0\framework\." 
  -Dsbt.boot.properties="file:///C:/Program%20Files/play-2.0/framework/sbt/sbt.boot.properties" 
  -jar"C:\Program Files\play-2.0\framework\sbt\sbt-launch.jar" run

And the error it produces:

java.io.IOException: The system cannot find the path specified
        at java.io.WinNTFileSystem.createFileExclusively(Native Method)
        at java.io.File.createNewFile(Unknown Source)
        at xsbt.boot.Locks$.apply0(Locks.scala:34)
        at xsbt.boot.Locks$.apply(Locks.scala:27)
        at scala.collection.mutable.FlatHashTable$class.$init$(Proxy.scala:32)
        at xsbt.boot.Launch$ScalaProvider.<init>(Launch.scala:110)
        at xsbt.boot.Launch$$anonfun$1.apply(Launch.scala:84)
        at org.apache.ivy.plugins.namespace.NamespaceRule.newEntry(Cache.scala:17)
        at org.apache.ivy.plugins.namespace.NamespaceRule.apply(Cache.scala:12)
        at xsbt.boot.Launch.getScala(Launch.scala:86)
        at xsbt.boot.Launch$.run(Launch.scala:49)
        at xsbt.boot.Launch$$anonfun$explicit$1.apply(Launch.scala:43)
        at xsbt.boot.Launch$.launch(Launch.scala:68)
        at xsbt.boot.Launch$.apply(Launch.scala:14)
        at xsbt.boot.Boot$.runImpl(Boot.scala:25)
        at xsbt.boot.Boot$.main(Boot.scala:15)
        at xsbt.boot.Boot.main(Boot.scala)
Error during sbt execution: java.io.IOException: The system cannot find the path specified

Unfortunately, I think it's now reached the point where UAC is preventing it from writing to Program Files. When I try the same command on a terminal running as administrator, it works much better and actually boots - which means the patches are correct. I don't know if there's any safe way round UAC.

Marcus Downing
mar...@bang-on.net



--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.


Kevin Bosman

unread,
Apr 28, 2012, 9:35:23 PM4/28/12
to play-fr...@googlegroups.com
> Unfortunately, I think it's now reached the point where UAC is preventing it
> from writing to Program Files. When I try the same command on a terminal
> running as administrator, it works much better and actually boots - which
> means the patches are correct. I don't know if there's any safe way round
> UAC.

Ah yes. The dreaded UAC. Ideally, you would have to add write
permissions to the subtree beneath your install location for your
logged on user(s), so Play can create its build files.

I suppose this boils back down to your initial suggestion of an
install system of some kind. However, I do not see that happening by
the Play devs. I'd imagine it's way out of scope.... But that leaves
an opening for you to jump in! ;)

Kevin Bosman

unread,
Apr 28, 2012, 10:02:31 PM4/28/12
to play-fr...@googlegroups.com
submitted pull request #270 as proposal to fix this problem:
https://github.com/playframework/Play20/pull/270

see also Lighthouse ticket #308:
https://play.lighthouseapp.com/projects/82401-play-20/tickets/308

Marcus Downing

unread,
Apr 29, 2012, 6:29:57 PM4/29/12
to play-fr...@googlegroups.com
I've made some progress on getting past UAC. My own copy of the batch scripts is now so peppered with rem and echo statements it's unrecognisable, but the edits I've made to build.bat are roughly:

echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\play.vbs"
echo UAC.ShellExecute "cmd", "/k java -Xms512M -Xmx1024M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M %DEBUG_PARAM% 
  -Dfile.encoding=UTF8 -Dplay.version=%PLAY_VERSION% 
  -Dsbt.ivy.home=""%~dp0..\repository"" 
  -Dplay.home=""%~dp0."" 
  -Dsbt.boot.properties=""%fp%sbt/sbt.boot.properties"" 
  -jar ""%~dp0sbt\sbt-launch.jar"" %* ", "%cd%", "runas", 1 >> "%temp%\play.vbs"
"%temp%\getadmin.vbs"

(Without the newlines inside the string, that's just for readability)  Note the use of double-double-quotes ("") to escape quotes within strings; the cmd /k which is used to make the window persistent (otherwise it disappears before you can read the response); and the %cd% variable representing the current directory. This now brings up the UAC permission prompt, and if the user says yes it spawns a new command line window that says:

[info] Set current project to default-c34ae0 (in build file:/C:/Windows/System32/)
java.lang.RuntimeException: No main class detected.
        at scala.sys.package$.error(package.scala:27)
[error] {file:/C:/Windows/System32/}default-c34ae0/compile:run: No main class detected.
[error] Total time: 0 s, completed 29-Apr-2012 23:28:00

Which suggests it's not getting the working path set correctly. Ah well, one step closer.

Kevin Bosman

unread,
Apr 30, 2012, 2:56:39 AM4/30/12
to play-fr...@googlegroups.com
You'd have to pass the current directory (%~dp0) to the vbs script and
cd to it before actually calling java.

*But*, I really don't believe that you should be running Play as admin.
IMHO, that's an overkill, and a security risk.

Apart from the spaces in paths problem that we've resolved, the only
reason why there's still a problem running Play from your Program
Files by default, is because of the write restrictions on that
hierarchy. If you simply add full control permissions to your local
user on the Program Files\Play20 subtree, you should be fine from
there on.

Perhaps you can change your UAC script to perform the permissions
change for the currently logged on user. You could save that as
play-setup.vbs, since it should only need to be executed once.

Marcus Downing

unread,
Apr 30, 2012, 12:45:38 PM4/30/12
to play-fr...@googlegroups.com
I see your point that running as admin is a bad idea.

In theory permissions would only need setting once, when Play is first installed. In practice file permissions are fragile things, that could be changed for any number of reasons. Ideally, the script would check the permissions of all the relevant files and only prompt for UAC if it finds that something needs changing.

Is there a list of the specific folders and files which need to be writable?

Kevin Bosman

unread,
Apr 30, 2012, 1:16:58 PM4/30/12
to play-fr...@googlegroups.com
> Is there a list of the specific folders and files which need to be writable?

I'm not 100% sure since I personally build & run play myself from trunk.

But I would imagine it would need at least framework/sbt/boot/. Note
that this folder probably will not exist initially, so you'll need to
create it first if it doesn't exist, or provide create folder
permissions in framework/sbt.
It will probably also need to write an .sbt.ivy.lock file into
repository/, and ivy may possibly need further write access beneath
there as well.
Reply all
Reply to author
Forward
0 new messages