ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Morten Mortensen <morten.morten...@tietoenator.com>
Subject RE: help wanted - escaping from quotes
Date Wed, 30 Jul 2003 21:17:37 GMT

Hi Jorge,

Hmmmm... It might be, that I am a bit ignorant. I did not take Jini into
account.

I *think*, I have an answer for you! Together with an explanation.


I just considered this small Java-program:

-----
public class Test
{
  public static void main(String[] arg)
  {
    String property="java.rmi.server.codebase";
    System.out.println("Property : >"+property+"<");

    String value=System.getProperty(property);
    System.out.println("Value:   : >"+value+"<");
  }
}
-----

If we play around with this on the command-line on a "random" OS of mine,
then we get -

-----
C:\test117>java
"-Djava.rmi.server.codebase=file:///${basedir}/build/classes/ fi
le:///${basedir}/lib/jini/jini-core.jar" Test
Property : >java.rmi.server.codebase<
Value:   : >file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-c
ore.jar<

C:\test117>java
-Djava.rmi.server.codebase="file:///${basedir}/build/classes/ fi
le:///${basedir}/lib/jini/jini-core.jar" Test
Property : >java.rmi.server.codebase<
Value:   : >file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-c
ore.jar<

C:\test117>java
"-Djava.rmi.server.codebase=\"file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-core.jar\"" Test
Property : >java.rmi.server.codebase<
Value:   : >"file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-
core.jar"<

C:\test117>
-----

If we really like this value, the first of the two forms is the correct one,
because java should just be fed a single argument "-D...=...". The second
works - here by me - because the combination of the cmd-shell and
::CreateProcess() is somewhat... tolerant (who ever got the idea of putting
all arguments to the process in a single string instead of in an array of
individual arguments???).

You really want the equivalent of -

Value:   : >"file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-c
ore.jar"<

- ? The Jini-folks say this? You are sure, that it is not just for the
command-line, not the actual property-value? Hmmm. Where do they say this?


Lets play around with a build-file! The file -

-----
<project name="Test" default="tryme">

  <target name="tryme">

    <echo>#1</echo>
    <java classname="Test" fork="true">
      <jvmarg
value="-Djava.rmi.server.codebase=file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-core.jar"/>
    </java>

    <echo>#2</echo>
    <java classname="Test" fork="true">
      <jvmarg value='-Djava.rmi.server.codebase=XXX XXX'/>
    </java>

    <echo>#3</echo>
    <java classname="Test" fork="true">
      <jvmarg value='-Djava.rmi.server.codebase="XXX XXX"'/>
    </java>

    <echo>#4</echo>
    <java classname="Test" fork="true">
      <jvmarg value='-Djava.rmi.server.codebase=\"XXX XXX\"'/>
    </java>

    <echo>#5</echo>
    <java classname="Test" fork="true">
      <jvmarg
value='-Djava.rmi.server.codebase="file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-core.jar"'/>
    </java>

    <echo>#6</echo>
    <java classname="Test" fork="true">
      <jvmarg
value='-Djava.rmi.server.codebase=\"file:///${basedir}/build/classes/
file:///${basedir}/lib/jini/jini-core.jar\"'/>
    </java>

  </target>

</project>
-----

- produces -

-----
C:\test117>ant
Buildfile: build.xml

tryme:
     [echo] #1
     [java] Property : >java.rmi.server.codebase<
     [java] Value:   : >file:///C:\test117/build/classes/
file:///C:\test117/lib
/jini/jini-core.jar<


     [echo] #2
     [java] Property : >java.rmi.server.codebase<
     [java] Value:   : >XXX XXX<


     [echo] #3
     [java] java.lang.NoClassDefFoundError: XXX
     [java] Exception in thread "main"

     [java] Java Result: 1
     [echo] #4
     [java] Property : >java.rmi.server.codebase<
     [java] Value:   : >"XXX XXX"<


     [echo] #5
     [java] java.lang.NoClassDefFoundError:
file:///C:\test117/lib/jini/jini-cor
e/jar
     [java] Exception in thread "main"

     [java] Java Result: 1
     [echo] #6
     [java] Property : >java.rmi.server.codebase<
     [java] Value:   : >"file:///C:\test117/build/classes/
file:///C:\test117/li
b/jini/jini-core.jar"<



BUILD SUCCESSFUL
Total time: 1 second
C:\test117>
-----

The first #1 is exactly equivalent to the first of the commandline-examples.


*** #6 is the effect, which you want? For your Jini-stuff to work?? ***


BUT WHY DOES #3 not work, but #4/#6 does? What happens?

Well, guessing is bad, but let me try - for the fun of it - I think my guess
is qualified. In #3 -

    <java classname="Test" fork="true">
      <jvmarg value='-Djava.rmi.server.codebase="XXX XXX"'/>
    </java>

- Ant *probably* does call
"http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#exec(java.la
ng.String[], java.lang.String[], java.io.File)", which refers the method -

public Process exec(String[] cmdarray,
                    String[] envp,
                    File dir)
             throws IOException

Here, one entry in "cmdarray" is >-Djava.rmi.server.codebase="XXX XXX"<.
What the JDK does - I belive to have seen this in the source-code for JDK
1.3.x once - all entries in "cmdarray" must - on Windows - be combined into
one, because the Win32-API-method "::CreateProcess()" for creating new
processes requires all arguments to be a single string - it parses the
string looking for quotes '"'.

The "Runtime.exec()" puts '"' around all entries from "cmdarry", combines
them with a space in between each, and uses this for "::CreateProcess()". In
our case, the string becomes -

>"-Djava.rmi.server.codebase="XXX XXX""<

The interpretation is, that >-Djava.rmi.server.codebase=< (by matching the
quotes) and >XXX< form a single argument (since there is no space in between
the two) and that - likewise - >XXX< and >< (the empty string between the
two last quotes) form a single, second argument. So -

    <echo>#3</echo>
    <java classname="Test" fork="true">
      <jvmarg value='-Djava.rmi.server.codebase="XXX XXX"'/>
    </java>

- is exactly equivalent to the command-line -

C:\test117>java -Djava.rmi.server.codebase=XXX XXX Test
Exception in thread "main" java.lang.NoClassDefFoundError: XXX

Here, "XXX" is supposed to be a class and "Test" the first argument to the
class.

     -----

I THINK, that there could be an error within the JDK (for Windows); quotes
'"' within arguments should be pre-fixed with '\' to take account for
"::CreateProcess"()".
I have *not* looked into the source-code recently - I *migth* be wrong here;
am still guessing! In the back of my head, I somehow think, that Sun
actually did this escaping *correctly*, once.... hmmm.... Think so.

IF ANT DOES USE the... *flat* "exec()"-method -

public Process exec(String command,
                    String[] envp,
                    File dir)
             throws IOException

- then, well, the Ant-team should receive a new bug-report, I think.

The "exec()" with a single command-string should never, *ever* be used from
within Java-code, if possible. Because then the JDK can handle it, if done
right.

     -----

I have no idea, if the solution #3/#6 works on Solaris, Linux and other
non-Windows platforms. What are you using?

By the way, back-slashes in a "file-URL" like in the above examples is not a
valid file-URL, I belive - resulting from expanding "${basedir}". It should
be replaced with '/' and form e.g. "file:///C:/test117/build/classes/".

     -----

Yes, I know, I am a tough mother-fucker.

Med venlig hilsen 
  Morten Sabroe Mortensen 
  TietoEnator A/S, Ved Lunden 12, 8230 Åbyhøj, Danmark 
  mailto:Morten.Mortensen@tietoenator.com 
  http://www.tietoenator.com


-----Original Message-----
From: Jorge Pereira [mailto:jcp@inescporto.pt]
Sent: 30. juli 2003 12:50
To: user@ant.apache.org
Subject: Re: help wanted - escaping from quotes


Hi Morten,

     First thanks for your replay.

     The problem is that if i do as you say (and i have tested this
before) the second URL does not apear in the rmi property and the rmid
can't download the jini classes. So it gives a "no class def found
/net/jini/core/something".

     In the sun documentation they say (and that is true) that, whenener
more that one url is neaded one must put the diferent url's in quotes
separated by a space in the refered java.rmi.server.codebase.

     The problem is that the jvmargs tag does not do this. I think you
are right. My first atempt was to put as you say, in the ant build.xml
but with no success.

     I think this is a bug in the ant <jvmargs> tag, but, until now, i
did not have a response from the ant team.

     So if i do:
         <jvmarg
value="-Djava.rmi.server.codebase=file:///${basedir}/build/classes/
file:///$basedir/lib/jini/jini-core.jar" />
         - jmarg only provides the first url to forked jvm;
     and like this:
         <jvmarg
value='-Djava.rmi.server.codebase="file:///${basedir}/build/classes/
file:///$basedir/lib/jini/jini-core.jar"' />
         - jmarg only provides the first url to forked jvm with the first
quote, so "file:/// is an unknown protocol.

So anymore suggestions ???

     Regards,
         Jorge Pereira


Morten Mortensen wrote:

 >Hi Jorge,
 >
 >You really want your quotes like -
 >
 >"-Djava.rmi.server.codebase=file:///${basedir}/build/classes/
 >file:///$basedir/lib/jini/jini-core.jar"
 >
 >- on the command-line!
 >
 >When you feed in a single "jvmarg" to Ant, the quotes are not necessary
 >- in fact, the quotes are *not* part of the file-URL, but does become part
 >of the file-URL; try how things work out without them!
 >
 >Regards,
 >  Morten Sabroe Mortensen
 >
 >
 >-----Original Message-----
 >From: Jorge Pereira
 >To: user@ant.apache.org
 >Sent: 29-07-03 17:52
 >Subject: help wanted - escaping from quotes
 >
 >hi,
 >
 >    i have to pass the following argument to a class for RMID download
 >of stubs:
 >
 >-Djava.rmi.server.codebase="file:///${basedir}/build/classes/
 >file:///$basedir/lib/jini/jini-core.jar"
 >
 >the previous line, works fine on the command line.
 >
 >But in the ant this doesn't work.
 >
 >I tryed :
 >
 ><jvmarg
 >value='-Djava.rmi.server.codebase="file:///${basedir}/build/classes/
 >file:///$basedir/lib/jini/jini-core.jar"' />
 >
 >but i gives me an error like this one :
 >
 >java.net.MalformedURLException: no protocol:
 >"file:///home/mypath/build/classes/
 >
 >Does anyone tryed this ???
 >
 >thanks in advance.
 >
 >Jorge Pereira
 >
 >
 >
 >---------------------------------------------------------------------
 >To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
 >For additional commands, e-mail: user-help@ant.apache.org
 >
 >
 >




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Mime
View raw message