Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #23473 > unrolled thread
| Started by | Roedy Green <see_website@mindprod.com.invalid> |
|---|---|
| First post | 2013-04-16 15:48 -0700 |
| Last post | 2013-04-27 22:31 -0400 |
| Articles | 20 on this page of 86 — 16 participants |
Back to article view | Back to comp.lang.java.programmer
exec problem is JDK 1.7.0_21 Roedy Green <see_website@mindprod.com.invalid> - 2013-04-16 15:48 -0700
Re: exec problem is JDK 1.7.0_21 Lew <lewbloch@gmail.com> - 2013-04-16 16:48 -0700
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-20 13:00 +0300
Re: exec problem is JDK 1.7.0_21 Joerg Meier <joergmmeier@arcor.de> - 2013-04-20 15:13 +0200
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-20 19:07 +0300
Re: exec problem is JDK 1.7.0_21 markspace <markspace@nospam.nospam> - 2013-04-20 09:24 -0700
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-20 19:34 +0300
Re: exec problem is JDK 1.7.0_21 markspace <markspace@nospam.nospam> - 2013-04-20 11:01 -0700
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 00:25 +0300
Re: exec problem is JDK 1.7.0_21 Joerg Meier <joergmmeier@arcor.de> - 2013-04-20 22:03 +0200
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 00:29 +0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-20 21:56 +0000
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 08:31 +0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-21 11:08 +0000
Re: exec problem is JDK 1.7.0_21 Arved Sandstrom <asandstrom2@eastlink.ca> - 2013-04-21 13:43 -0300
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 23:12 +0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-21 21:17 +0000
Re: exec problem is JDK 1.7.0_21 Arne Vajhøj <arne@vajhoej.dk> - 2013-04-27 22:49 -0400
Re: exec problem is JDK 1.7.0_21 Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-04-20 15:03 -0700
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 08:26 +0300
Re: exec problem is JDK 1.7.0_21 "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-04-21 14:30 +0100
Re: exec problem is JDK 1.7.0_21 Knute Johnson <nospam@knutejohnson.com> - 2013-04-21 09:20 -0700
Re: exec problem is JDK 1.7.0_21 markspace <markspace@nospam.nospam> - 2013-04-21 11:31 -0700
Re: exec problem is JDK 1.7.0_21 Arved Sandstrom <asandstrom2@eastlink.ca> - 2013-04-21 16:06 -0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-21 19:47 +0000
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-21 23:01 +0000
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 23:29 +0300
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 23:45 +0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-21 21:38 +0000
Re: exec problem is JDK 1.7.0_21 Knute Johnson <nospam@knutejohnson.com> - 2013-04-21 18:49 -0700
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-22 09:36 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-22 10:39 +0100
Re: exec problem is JDK 1.7.0_21 Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-04-22 07:43 -0700
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-22 19:33 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-23 07:30 +0100
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-22 21:07 +0000
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-23 23:28 +0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-23 21:05 +0000
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-24 11:22 +0300
Re: exec problem is JDK 1.7.0_21 Martin Gregorie <martin@address-in-sig.invalid> - 2013-04-24 20:22 +0000
Re: exec problem is JDK 1.7.0_21 Nigel Wade <nmw@ion.le.ac.uk> - 2013-04-24 11:24 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 23:23 +0300
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-21 00:40 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-23 10:48 +0100
Re: exec problem is JDK 1.7.0_21 Donkey Hottie <donkey@fredriksson.dy.fi> - 2013-04-23 13:31 +0300
<? extends String> (was: exec problem is JDK 1.7.0_21) Steven Simpson <ss@domain.invalid> - 2013-04-23 14:55 +0100
Re: <? extends String> lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-04-23 16:37 +0100
Re: <? extends String> Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-04-23 08:50 -0700
Re: <? extends String> lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-04-23 17:30 +0100
Re: <? extends String> Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-04-23 09:58 -0700
Re: <? extends String> Donkey Hottie <donkey@fredriksson.dy.fi> - 2013-04-23 21:06 +0300
Re: <? extends String> lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-04-23 19:33 +0100
Re: <? extends String> Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-04-23 12:26 -0700
Re: <? extends String> lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-04-24 09:08 +0100
Re: <? extends String> Arved Sandstrom <asandstrom2@eastlink.ca> - 2013-04-23 16:28 -0300
Re: <? extends String> (was: exec problem is JDK 1.7.0_21) Lew <lewbloch@gmail.com> - 2013-04-23 14:12 -0700
Re: <? extends String> Steven Simpson <ss@domain.invalid> - 2013-04-23 23:22 +0100
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-23 19:56 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-23 23:31 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-23 23:39 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-24 09:29 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-24 10:26 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-24 13:11 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-24 22:24 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-25 11:49 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-25 10:19 +0100
Re: exec problem is JDK 1.7.0_21 "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-04-25 09:02 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-25 11:47 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-25 09:50 +0100
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-25 10:07 +0100
Re: exec problem is JDK 1.7.0_21 "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-04-27 08:44 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-26 20:17 +0300
Re: exec problem is JDK 1.7.0_21 Steven Simpson <ss@domain.invalid> - 2013-04-27 09:22 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-27 12:39 +0300
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-23 23:17 +0300
Re: exec problem is JDK 1.7.0_21 Arved Sandstrom <asandstrom2@eastlink.ca> - 2013-04-23 17:32 -0300
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-24 10:39 +0300
Re: exec problem is JDK 1.7.0_21 "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-04-25 09:02 +0100
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-25 11:59 +0300
Re: exec problem is JDK 1.7.0_21 Arved Sandstrom <asandstrom2@eastlink.ca> - 2013-04-25 18:38 -0300
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-28 10:57 +0300
Re: exec problem is JDK 1.7.0_21 Arne Vajhøj <arne@vajhoej.dk> - 2013-04-27 22:35 -0400
Re: exec problem is JDK 1.7.0_21 Sven Köhler <remove-sven.koehler@gmail.com> - 2013-04-28 09:23 +0300
Re: exec problem is JDK 1.7.0_21 Arne Vajhøj <arne@vajhoej.dk> - 2013-04-28 09:52 -0400
Re: exec problem is JDK 1.7.0_21 Stanimir Stamenkov <s7an10@netscape.net> - 2013-04-20 17:52 +0300
Re: exec problem is JDK 1.7.0_21 Arne Vajhøj <arne@vajhoej.dk> - 2013-04-27 22:31 -0400
Page 2 of 5 — ← Prev page 1 [2] 3 4 5 Next page →
| From | "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> |
|---|---|
| Date | 2013-04-21 14:30 +0100 |
| Message-ID | <qfqdncXu7dgzd-7MnZ2dnUVZ8vKdnZ2d@bt.com> |
| In reply to | #23544 |
Sven Köhler wrote:
> The documentation speaks of "operating systems where programs are
> expected to tokenize command line strings themselves". Windows is that
> type of operating systems.
Agreed. At least at the Win32 API level (the lowest level that normal mortals
get to use). As noted elsethread some compilers/libraries for C and C++ on
Windows do the argument parsing for you, but that's just a convenience hack in
libc -- and only applies to command-line programs anyway.
> For that type of operating system, the list
> of strings shall contain exactly two elements.
The documentation doesn't say that on such systems the list MUST contain
exactly two elements, it states (my emphasis):
"on such a system a Java implementation MIGHT require commands to contain
exactly two elements"
Or, to put it another way: the only way to find out what works is to experiment
(it probably depends on the application you're launching as well as the OS and
Java platform). A right pain in the bum...
> Source:
> http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
> And in fact, I can confirm that ProcessBuilder passes the second element
> of the string list to the invoked external program - however only if the
> argument starts and ends with a quote.
Nothing like experiment :-) But two questions: what version of windows were
you using ? And what kind of external application were you testing it with ?
For the last question I mean was it a C/C++ program compiled for the
command-line, a Win32 GUI program writing to the MS-supplied C/C++ libraries,
a .NET program, a Delphi (or some other language) program, a Java program, a
Cygwin executable ??. All of these might -- and I suspect often do -- have
different rules...
-- chris
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@knutejohnson.com> |
|---|---|
| Date | 2013-04-21 09:20 -0700 |
| Message-ID | <kl13eq$3bh$1@dont-email.me> |
| In reply to | #23550 |
On 4/21/2013 6:30 AM, Chris Uppal wrote:
> Nothing like experiment :-) But two questions: what version of windows were
> you using ? And what kind of external application were you testing it with ?
> -- chris
I haven't followed this thread closely enough to really understand the
controversy. But I like experiments. And I never get to write anything
in C any more.
Windows XP (the results on Xubuntu 12.10 are identical)
One quoted argument "hello world"
C:\Documents and Settings\Knute Johnson>java test
argc=2
argv[0]=C:\Documents and Settings\Knute Johnson\test.exe
argv[1]=hello world
exitValue=123
Two arguments
C:\Documents and Settings\Knute Johnson>java test
argc=3
argv[0]=C:\Documents and Settings\Knute Johnson\test.exe
argv[1]=hello
argv[2]=world
exitValue=123
---
#include <stdio.h>
int main(int argc, char** argv) {
int i = 0;
printf("argc=%d\n",argc);
for (i=0; i<argc; i++)
printf("argv[%d]=%s\n",i,argv[i]);
return 123;
}
---
import java.io.*;
public class test {
public static void main(String[] args) throws Exception {
ProcessBuilder pb = new ProcessBuilder("test.exe","hello world");
// ProcessBuilder pb = new
ProcessBuilder("test.exe","hello","world");
pb.redirectError(new File("error"));
Process p = pb.start();
final InputStream is = p.getInputStream();
Thread t = new Thread(new Runnable() {
public void run() {
int n;
try {
while ((n = is.read()) != -1)
System.out.print((char)n);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
t.start();
t.join();
System.out.println("exitValue=" + p.exitValue());
}
}
--
Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | markspace <markspace@nospam.nospam> |
|---|---|
| Date | 2013-04-21 11:31 -0700 |
| Message-ID | <kl1b47$5q5$1@dont-email.me> |
| In reply to | #23551 |
On 4/21/2013 9:20 AM, Knute Johnson wrote:
> I haven't followed this thread closely enough to really understand the
> controversy. But I like experiments. And I never get to write anything
> in C any more.
I'm just too lazy to do this sort of thing. I applaud those of you who
are able to go above and beyond all reasonable efforts helping people.
I think the OP has just got a bee up his butt about the documentation
and won't stop to consider he may be reading it wrong. Your experiments
match what I assumed to be the case.
> ProcessBuilder pb = new ProcessBuilder("test.exe","hello world");
> argc=2
> ProcessBuilder pb = new ProcessBuilder("test.exe","hello","world");
> argc=3
Yup, that's what I thought. I'm really uncertain what the heck the OP
is on about.
[toc] | [prev] | [next] | [standalone]
| From | Arved Sandstrom <asandstrom2@eastlink.ca> |
|---|---|
| Date | 2013-04-21 16:06 -0300 |
| Message-ID | <OMWct.85$TR6.41@newsfe21.iad> |
| In reply to | #23553 |
On 04/21/2013 03:31 PM, markspace wrote:
> On 4/21/2013 9:20 AM, Knute Johnson wrote:
>> I haven't followed this thread closely enough to really understand the
>> controversy. But I like experiments. And I never get to write anything
>> in C any more.
>
> I'm just too lazy to do this sort of thing. I applaud those of you who
> are able to go above and beyond all reasonable efforts helping people. I
> think the OP has just got a bee up his butt about the documentation and
> won't stop to consider he may be reading it wrong. Your experiments
> match what I assumed to be the case.
>
> > ProcessBuilder pb = new ProcessBuilder("test.exe","hello world");
>> argc=2
>
> > ProcessBuilder pb = new ProcessBuilder("test.exe","hello","world");
>> argc=3
>
> Yup, that's what I thought. I'm really uncertain what the heck the OP
> is on about.
>
>
I think the points that Martin and Chris made is that for
system-specific access of this nature you don't even make too many
assumptions at all. You just do the experimentation that they described,
for the specific OS and program in question.
I can see why the guys work up a problem, it's fun, I've done it myself.
I do it when I don't actually know for a fact, so I code up a simple
app, in whatever. I'm the first one to admit, I often don't know off the
top of my head, which is why I am empirical. :-)
I'm impressed with the guys that master a platform or language so well
that they are Knuthian, no need to run code, they know their statements
are correct. I can't do that myself, just in the last 12 months I've had
to deal with maybe 8-10 different programming languages, several dozen
new systems and APIs, and several dozen specifications. I have no idea
what the guys do that understand languages or OS systems programming or
concurrency like mother's milk come from, but they aren't EAI
consultants. :-)
AHS
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-04-21 19:47 +0000 |
| Message-ID | <kl1for$b5h$1@dont-email.me> |
| In reply to | #23554 |
On Sun, 21 Apr 2013 16:06:21 -0300, Arved Sandstrom wrote:
> I think the points that Martin and Chris made is that for
> system-specific access of this nature you don't even make too many
> assumptions at all. You just do the experimentation that they described,
> for the specific OS and program in question.
>
And not forgetting the test code that Knute published, which I was too
lazy to write. The only change I'd have made was to write:
public static void main(String[] args)
{
ProcessBuilder pb = new ProcessBuilder(args);
....
This is a bit more flexible because it can handle both our test cases and
a lot more besides, including trying an empty String array, using an
unknown program name as the first argument or trying to run a script (in
Linux this script runs:
#!/bin/bash
i=0
echo "$# arguments"
for f in $*
do
echo "arg[$i]=$f"
i=$(expr $i + 1)
done
exit $i
$ java TestProcessBuilder testscript hello world
2 arguments
arg[0]=hello
arg[1]=world
exitValue=2
...though this script doesn't honour spaces within arguments.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-04-21 23:01 +0000 |
| Message-ID | <kl1r4l$hrb$1@dont-email.me> |
| In reply to | #23555 |
On Sun, 21 Apr 2013 19:47:39 +0000, Martin Gregorie wrote:
> ...though this script doesn't honour spaces within arguments.
>
This niggled me, so here's a replacement for 'testscript' which *does*
honour quoted command line arguments:
$ cat testscript
#!/bin/bash
i=0
echo "$# arguments"
for f in "$@"
do
echo "arg[$i]=$f"
i=$(expr $i + 1)
done
exit $i
$
Tested and shown to work in my version of the SSCE:
$ java TestProcessBuilder testscript a cat and "a mouse in its hole"
4 arguments
arg[0]=a
arg[1]=cat
arg[2]=and
arg[3]=a mouse in its hole
exitValue=4
$
The fix was changing echo ' for f in $* ' to ' for f in "$@" '.
For completeness, here's my version of the ProcessBuilder SSCE. As well
as grabbing the ProcessBuilder constructor arguments from the command
line, I made Exception trapping explicit so where they're issued is
unambiguous and made the Runnable class into a named class:
import java.io.*;
public class TestProcessBuilder
{
public static void main(String[] args) throws Exception
{
try
{
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
Process p = pb.start();
Thread t = new Thread(new TestRunnable(p.getInputStream()));
t.start();
t.join();
print("exitValue=%d", p.exitValue());
}
catch(NullPointerException e)
{
print("ProcessBuilder.start() threw NullPointerException %s",
e.getMessage());
}
catch(IndexOutOfBoundsException e)
{
print("ProcessBuilder.start() threw IndexOutBoundsException %s",
e.getMessage());
}
catch(IOException e)
{
print("ProcessBuilder.start() threw IOException %s",
e.getMessage());
}
}
private static void print(String format, String value)
{
System.out.println(String.format(format, value));
}
private static void print(String format, int value)
{
System.out.println(String.format(format, value));
}
}
import java.io.*;
public class TestRunnable implements Runnable
{
private InputStream is;
public TestRunnable(InputStream is)
{
this.is = is;
}
public void run()
{
int n;
try
{
while ((n = is.read()) != -1)
System.out.print((char)n);
}
catch (IOException ioe)
{
System.out.println("IOException in TestRunnable");
ioe.printStackTrace();
}
}
}
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Sven Köhler <remove-sven.koehler@gmail.com> |
|---|---|
| Date | 2013-04-21 23:29 +0300 |
| Message-ID | <atj0htFhj68U1@mid.dfncis.de> |
| In reply to | #23551 |
Am 21.04.2013 19:20, schrieb Knute Johnson:
> One quoted argument "hello world"
new ProcessBuilder("test.exe", "hello world");
new ProcessBuilder("test.exe", "\"hello world\"");
new ProcessBuilder("test.exe", "\"hello\" \"world\"");
Run that on Windows as well as on something UNIX like - e.g. Linux.
Regards,
Sven
[toc] | [prev] | [next] | [standalone]
| From | Sven Köhler <remove-sven.koehler@gmail.com> |
|---|---|
| Date | 2013-04-21 23:45 +0300 |
| Message-ID | <atj1efFhpl1U1@mid.dfncis.de> |
| In reply to | #23558 |
Am 21.04.2013 23:29, schrieb Sven Köhler:
> Am 21.04.2013 19:20, schrieb Knute Johnson:
>> One quoted argument "hello world"
>
> new ProcessBuilder("test.exe", "hello world");
> new ProcessBuilder("test.exe", "\"hello world\"");
> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
Let me add
new ProcessBuilder("test.exe", "\"\\\"hello world\\\"\"");
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-04-21 21:38 +0000 |
| Message-ID | <kl1m9h$e5t$2@dont-email.me> |
| In reply to | #23558 |
On Sun, 21 Apr 2013 23:29:59 +0300, Sven Köhler wrote:
> Am 21.04.2013 19:20, schrieb Knute Johnson:
>> One quoted argument "hello world"
>
> new ProcessBuilder("test.exe", "hello world");
> new ProcessBuilder("test.exe", "\"hello world\"");
> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
>
> Run that on Windows as well as on something UNIX like - e.g. Linux.
>
That tells us nothing: there's no indication of:
- how you call ProcessBuilder
- the environment you're running
- what "test.exe" does.
- what it receives when its run with the arguments you've listed above.
Since you're calling us liars, you need to do a lot better than that.
Specifically, you need to post:
1) An SSCE, i.e. a short, complete Java program that calls ProcessBuilder,
returns output from the program it runs and, crucially, can be cut and
pasted from your post and compiled and run without needing any changes.
2) The source code for the program ProcessBuilder is to run, test.exe,
that can be cut and pasted from your post and compiled and run without
needing any changes.
3) Output that you got showing the arguments supplied to ProcessBuilder
and the corresponding output from test.exe
Seeing that you're so sure we're wrong, it follows that you already have
that code and have run it. IOW you can post it and the test results right
now.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@knutejohnson.com> |
|---|---|
| Date | 2013-04-21 18:49 -0700 |
| Message-ID | <kl24qh$85h$1@dont-email.me> |
| In reply to | #23558 |
On 4/21/2013 1:29 PM, Sven Köhler wrote:
> Am 21.04.2013 19:20, schrieb Knute Johnson:
>> One quoted argument "hello world"
>
> new ProcessBuilder("test.exe", "hello world");
> new ProcessBuilder("test.exe", "\"hello world\"");
> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
>
> Run that on Windows as well as on something UNIX like - e.g. Linux.
>
>
> Regards,
> Sven
>
I think ProcessBuilder strips out the quotes inside the String. The
little C program I wrote deals with them just fine from the command line
in XP.
--
Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | Sven Köhler <remove-sven.koehler@gmail.com> |
|---|---|
| Date | 2013-04-22 09:36 +0300 |
| Message-ID | <atk43iFoi7bU1@mid.dfncis.de> |
| In reply to | #23563 |
Am 22.04.2013 04:49, schrieb Knute Johnson:
> On 4/21/2013 1:29 PM, Sven Köhler wrote:
>> Am 21.04.2013 19:20, schrieb Knute Johnson:
>>> One quoted argument "hello world"
>>
>> new ProcessBuilder("test.exe", "hello world");
>> new ProcessBuilder("test.exe", "\"hello world\"");
>> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
>>
>> Run that on Windows as well as on something UNIX like - e.g. Linux.
>
> I think ProcessBuilder strips out the quotes inside the String. The
> little C program I wrote deals with them just fine from the command line
> in XP.
The output should have been:
1) argv[1]=hello world
2) argv[1]=hello world
3) argv[1]=hello
argv[2]=world
And in the fourth example I added, the output should have been
4) argv[1]="hello world"
ProcessBuilder does not strip any quotes. The logic it implements is as
follows: If the argument contains spaces, add quotes. If it already
starts/ends with a quote, don't modify it. ProcessBuilder does not
check, escape, or do anything else with quotes inside the argument
string. You can confirm that by looking at the sources available in the JDK.
Regards,
Sven
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@domain.invalid> |
|---|---|
| Date | 2013-04-22 10:39 +0100 |
| Message-ID | <73df4a-rc3.ln1@s.simpson148.btinternet.com> |
| In reply to | #23564 |
On 22/04/13 07:36, Sven Köhler wrote:
> Am 22.04.2013 04:49, schrieb Knute Johnson:
>> On 4/21/2013 1:29 PM, Sven Köhler wrote:
>>> Am 21.04.2013 19:20, schrieb Knute Johnson:
>>>> One quoted argument "hello world"
>>> new ProcessBuilder("test.exe", "hello world");
>>> new ProcessBuilder("test.exe", "\"hello world\"");
>>> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
>>>
>>> Run that on Windows as well as on something UNIX like - e.g. Linux.
> The output should have been:
>
> 1) argv[1]=hello world
> 2) argv[1]=hello world
> 3) argv[1]=hello
> argv[2]=world
>
> And in the fourth example I added,
> new ProcessBuilder("test.exe", "\"\\\"hello world\\\"\"");
> the output should have been
>
> 4) argv[1]="hello world"
I tested by cross-compiling a C program 'showargs' from Linux (with
mingw32):
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
printf("Arg count: %d\n", argc);
for (i = 0; i < argc; i++)
printf(" argv[%d]=[%s]\n", i, argv[i]);
return 0;
}
To invoke from Java, I used:
import java.io.*;
import java.util.*;
public class TestProcessBuilder {
public static void main(String[] args) throws Exception {
test("showargs", "hello world");
test("showargs", "\"hello world\"");
test("showargs", "\"hello\" \"world\"");
test("showargs", "\"\\\"hello world\\\"\"");
}
private static void test(String... args)
throws IOException, InterruptedException {
System.out.println("Java: " + Arrays.asList(args));
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
final Process proc = pb.start();
Thread t = new Thread() {
public void run() {
try (InputStream in = proc.getInputStream()) {
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > -1) {
System.out.write(buf, 0, len);
}
} catch (IOException ex) {
System.err.println("error: " + ex);
}
}
};
t.start();
proc.getOutputStream().close();
int rc = proc.waitFor();
t.join();
}
}
(I compiled this on Linux.)
On a Windows VM, I got this:
E:\>java -cp . TestProcessBuilder
Java: [showargs, hello world]
Arg count: 2
argv[0]=[showargs]
argv[1]=[hello world]
Java: [showargs, "hello world"]
Arg count: 2
argv[0]=[showargs]
argv[1]=[hello world]
Java: [showargs, "hello" "world"]
Arg count: 3
argv[0]=[showargs]
argv[1]=[hello]
argv[2]=[world]
Java: [showargs, "\"hello world\""]
Arg count: 2
argv[0]=[showargs]
argv[1]=["hello world"]
E:\>
'java -version' reports:
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
On Linux, I got this:
$ java -cp . TestProcessBuilder
Java: [showargs, hello world]
Arg count: 2
argv[0]=[showargs]
argv[1]=[hello world]
Java: [showargs, "hello world"]
Arg count: 2
argv[0]=[showargs]
argv[1]=["hello world"]
Java: [showargs, "hello" "world"]
Arg count: 2
argv[0]=[showargs]
argv[1]=["hello" "world"]
Java: [showargs, "\"hello world\""]
Arg count: 2
argv[0]=[showargs]
argv[1]=["\"hello world\""]
$
'java -version' report:
java version "1.7.0_15"
OpenJDK Runtime Environment (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.04.1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
--
ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Daniel Pitts <newsgroup.nospam@virtualinfinity.net> |
|---|---|
| Date | 2013-04-22 07:43 -0700 |
| Message-ID | <60cdt.4948$sI.1833@newsfe20.iad> |
| In reply to | #23566 |
On 4/22/13 2:39 AM, Steven Simpson wrote:
> On 22/04/13 07:36, Sven Köhler wrote:
>> Am 22.04.2013 04:49, schrieb Knute Johnson:
>>> On 4/21/2013 1:29 PM, Sven Köhler wrote:
>>>> Am 21.04.2013 19:20, schrieb Knute Johnson:
>>>>> One quoted argument "hello world"
>>>> new ProcessBuilder("test.exe", "hello world");
>>>> new ProcessBuilder("test.exe", "\"hello world\"");
>>>> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
>>>>
>>>> Run that on Windows as well as on something UNIX like - e.g. Linux.
>> The output should have been:
>>
>> 1) argv[1]=hello world
>> 2) argv[1]=hello world
>> 3) argv[1]=hello
>> argv[2]=world
>>
>> And in the fourth example I added,
>
>> new ProcessBuilder("test.exe", "\"\\\"hello world\\\"\"");
>
>> the output should have been
>>
>> 4) argv[1]="hello world"
>
>
> I tested by cross-compiling a C program 'showargs' from Linux (with
> mingw32):
>
> #include <stdio.h>
>
> int main(int argc, char **argv)
> {
> int i;
> printf("Arg count: %d\n", argc);
> for (i = 0; i < argc; i++)
> printf(" argv[%d]=[%s]\n", i, argv[i]);
> return 0;
> }
>
>
> To invoke from Java, I used:
>
> import java.io.*;
> import java.util.*;
>
> public class TestProcessBuilder {
> public static void main(String[] args) throws Exception {
> test("showargs", "hello world");
> test("showargs", "\"hello world\"");
> test("showargs", "\"hello\" \"world\"");
> test("showargs", "\"\\\"hello world\\\"\"");
> }
>
> private static void test(String... args)
> throws IOException, InterruptedException {
> System.out.println("Java: " + Arrays.asList(args));
> ProcessBuilder pb = new ProcessBuilder(args);
> pb.redirectErrorStream(true);
> final Process proc = pb.start();
> Thread t = new Thread() {
> public void run() {
> try (InputStream in = proc.getInputStream()) {
> byte[] buf = new byte[1024];
> int len;
> while ((len = in.read(buf)) > -1) {
> System.out.write(buf, 0, len);
> }
> } catch (IOException ex) {
> System.err.println("error: " + ex);
> }
> }
> };
> t.start();
> proc.getOutputStream().close();
> int rc = proc.waitFor();
> t.join();
> }
> }
>
> (I compiled this on Linux.)
>
>
> On a Windows VM, I got this:
>
> E:\>java -cp . TestProcessBuilder
> Java: [showargs, hello world]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=[hello world]
> Java: [showargs, "hello world"]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=[hello world]
> Java: [showargs, "hello" "world"]
> Arg count: 3
> argv[0]=[showargs]
> argv[1]=[hello]
> argv[2]=[world]
> Java: [showargs, "\"hello world\""]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=["hello world"]
>
> E:\>
>
> 'java -version' reports:
>
> java version "1.7.0_21"
> Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
> Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
>
>
>
> On Linux, I got this:
>
> $ java -cp . TestProcessBuilder
> Java: [showargs, hello world]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=[hello world]
> Java: [showargs, "hello world"]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=["hello world"]
> Java: [showargs, "hello" "world"]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=["hello" "world"]
> Java: [showargs, "\"hello world\""]
> Arg count: 2
> argv[0]=[showargs]
> argv[1]=["\"hello world\""]
> $
>
> 'java -version' report:
>
> java version "1.7.0_15"
> OpenJDK Runtime Environment (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.04.1)
> OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
Interesting, I expected the argv[1]=["hello world"] for the input "hello
world"]. It seems to be that way for Linux, but not on windows.
[toc] | [prev] | [next] | [standalone]
| From | Sven Köhler <remove-sven.koehler@gmail.com> |
|---|---|
| Date | 2013-04-22 19:33 +0300 |
| Message-ID | <atl71pF1ohsU1@mid.dfncis.de> |
| In reply to | #23567 |
Am 22.04.2013 17:43, schrieb Daniel Pitts:
> On 4/22/13 2:39 AM, Steven Simpson wrote:
>> test("showargs", "hello world");
>> test("showargs", "\"hello world\"");
>> test("showargs", "\"hello\" \"world\"");
>> test("showargs", "\"\\\"hello world\\\"\"");
Here are several other interesting ones:
test("showargs", "hello\" \" world");
test("showargs", "hello", "", "world");
test("showargs", "hello", "\"\"", "world");
test("showargs", "c:\\program files\\", "world");
test("showargs", "c:\\program files\\\\", "world");
test("showargs", "c:\\program files\\\\\\", "world");
> Interesting, I expected the argv[1]=["hello world"] for the input "hello
> world"]. It seems to be that way for Linux, but not on windows.
On Linux, the strings can be passed between processes "as-is" - without
adding quotes, escapes, or whatever. But on Windows, adding quotes and
escaping quotes that are part of the argument may be necessary. The
current ProcessBuilder implementation sucks at it. Also, no definitive
way of escaping quotes or backslashes exists, as each program could use
a different tokenizer. In practise, it's usually something compatible to
Microsoft's CommandLineToArgv function.
Regards,
Sven
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@domain.invalid> |
|---|---|
| Date | 2013-04-23 07:30 +0100 |
| Message-ID | <vcmh4a-6i7.ln1@s.simpson148.btinternet.com> |
| In reply to | #23568 |
On 22/04/13 17:33, Sven Köhler wrote:
> Here are several other interesting ones:
>
> test("showargs", "hello\" \" world");
> test("showargs", "hello", "", "world");
> test("showargs", "hello", "\"\"", "world");
> test("showargs", "c:\\program files\\", "world");
> test("showargs", "c:\\program files\\\\", "world");
> test("showargs", "c:\\program files\\\\\\", "world");
Java: [showargs, hello" " world]
Arg count: 3
argv[0]=[showargs]
argv[1]=[hello]
argv[2]=[ world]
Java: [showargs, hello, , world]
Arg count: 3
argv[0]=[showargs]
argv[1]=[hello]
argv[2]=[world]
Java: [showargs, hello, "", world]
Arg count: 4
argv[0]=[showargs]
argv[1]=[hello]
argv[2]=[]
argv[3]=[world]
Java: [showargs, c:\program files\, world]
Arg count: 3
argv[0]=[showargs]
argv[1]=[c:\program files\]
argv[2]=[world]
Java: [showargs, c:\program files\\, world]
Arg count: 2
argv[0]=[showargs]
argv[1]=[c:\program files\" world]
Java: [showargs, c:\program files\\\, world]
Arg count: 3
argv[0]=[showargs]
argv[1]=[c:\program files\\]
argv[2]=[world]
--
ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-04-22 21:07 +0000 |
| Message-ID | <kl48pm$qve$1@dont-email.me> |
| In reply to | #23563 |
On Sun, 21 Apr 2013 18:49:59 -0700, Knute Johnson wrote:
> On 4/21/2013 1:29 PM, Sven Köhler wrote:
>> Am 21.04.2013 19:20, schrieb Knute Johnson:
>>> One quoted argument "hello world"
>>
>> new ProcessBuilder("test.exe", "hello world");
>> new ProcessBuilder("test.exe", "\"hello world\"");
>> new ProcessBuilder("test.exe", "\"hello\" \"world\"");
>>
>> Run that on Windows as well as on something UNIX like - e.g. Linux.
>>
>>
>> Regards,
>> Sven
>>
>>
> I think ProcessBuilder strips out the quotes inside the String. The
> little C program I wrote deals with them just fine from the command line
> in XP.
My testprog works exactly the same when run from within my
TestProcessBuilder test class as it does when run stand-alone from the
command line:
$ java TestProcessBuilder testprog "hello world" "\"hello world\""
"\"hello\" \"world\"" "hello ""double quoted"" world"
argc=5
argv[0]=testprog
argv[1]=hello world
argv[2]="hello world"
argv[3]="hello" "world"
argv[4]=hello double quoted world
exitValue=5
$ testprog "hello world" "\"hello world\"" "\"hello\" \"world\"" "hello
""double quoted"" world"
argc=5
argv[0]=testprog
argv[1]=hello world
argv[2]="hello world"
argv[3]="hello" "world"
argv[4]=hello double quoted world
$
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Sven Köhler <remove-sven.koehler@gmail.com> |
|---|---|
| Date | 2013-04-23 23:28 +0300 |
| Message-ID | <ato974FmrfdU1@mid.dfncis.de> |
| In reply to | #23570 |
Am 23.04.2013 00:07, schrieb Martin Gregorie: > My testprog works exactly the same when run from within my > TestProcessBuilder test class as it does when run stand-alone from the > command line: > > $ java TestProcessBuilder testprog "hello world" "\"hello world\"" > "\"hello\" \"world\"" "hello ""double quoted"" world" > argc=5 > argv[0]=testprog > argv[1]=hello world > argv[2]="hello world" > argv[3]="hello" "world" Please look at the results that Steven posted. If the String "hello\" \"world" is passed to the ProcessBuilder, the result was: argv[1]=[hello] argv[2]=[world] Oh, and then there was the neat case, of passing the two argument strings "c:\program files\" and "world" to the ProcessBuilder. The case is neat, because the external process started by ProcessBuilder is invoked with the argument string representing the path c:\program files\" world Regards, Sven
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-04-23 21:05 +0000 |
| Message-ID | <kl6t2r$pvu$2@dont-email.me> |
| In reply to | #23598 |
On Tue, 23 Apr 2013 23:28:35 +0300, Sven Köhler wrote:
> Am 23.04.2013 00:07, schrieb Martin Gregorie:
>> My testprog works exactly the same when run from within my
>> TestProcessBuilder test class as it does when run stand-alone from the
>> command line:
>>
>> $ java TestProcessBuilder testprog "hello world" "\"hello world\""
>> "\"hello\" \"world\"" "hello ""double quoted"" world"
>> argc=5 argv[0]=testprog argv[1]=hello world argv[2]="hello world"
>> argv[3]="hello" "world"
>
> Please look at the results that Steven posted. If the String "hello\"
> \"world" is passed to the ProcessBuilder, the result was:
> argv[1]=[hello] argv[2]=[world]
>
Actually, on Linux almost all the messing about with strings is done by
the shell that invokes the the command if the strings are enclosed in
double quotes. Use single quotes instead and the strings arrive at the
program ProcessBuilder is running with no modification at all. Here are
the results of using (1) double quoted strings and (2) single quoted
strings.
$ java TestProcessBuilder testprog "hello world" "\"hello world\""
"\"hello\" \"world\"" "hello ""double quoted"" world"
argc=5
argv[0]=testprog
argv[1]=hello world
argv[2]="hello world"
argv[3]="hello" "world"
argv[4]=hello double quoted world
exitValue=5
$ java TestProcessBuilder testprog 'hello world' '\"hello world\"'
'\"hello\" \"world\"' 'hello ""double quoted"" world'
argc=5
argv[0]=testprog
argv[1]=hello world
argv[2]=\"hello world\"
argv[3]=\"hello\" \"world\"
argv[4]=hello ""double quoted"" world
exitValue=5
using the same TestProcessBuilder.java program as I used before. Note
that the *second* example is what will happen if the arguments are read
from an external source such as a file but, of course, if the arguments
are program literals embedded in the source text then the internal double
quotes inside them must be escaped like this:
====================== TestProcessBuilder2.java =======================
import java.io.*;
public class TestProcessBuilder2
{
public static void main(String[] args) throws Exception
{
String[] argList = { "testprog",
"hello world",
"\"hello world\"",
"\"hello\" \"world\"",
"hello \"\"double quoted\"\" world"};
ProcessBuilder pb = new ProcessBuilder(argList);
pb.redirectErrorStream(true);
Process p = pb.start();
Thread t = new Thread(new TestRunnable(p.getInputStream()));
t.start();
t.join();
System.out.println("exitValue=%d" + p.exitValue());
}
}
====================== TestProcessBuilder2.java =======================
$ java TestProcessBuilder2
argc=5
argv[0]=testprog
argv[1]=hello world
argv[2]="hello world"
argv[3]="hello" "world"
argv[4]=hello ""double quoted"" world
exitValue=%d5
$
> Oh, and then there was the neat case, of passing the two argument
> strings "c:\program files\" and "world" to the ProcessBuilder.
>
You need to show the exact code line(s) used for this: the exact detail
is critical because what you described above should not compile. Assuming
it is written as:
new ProcessBuilder("c:\program files\", "world");
then the first string is actually "c:\program files\", " because the
second quote was escaped and so looses its meaning as a string
terminator. This leaves the sequence [world"] with an unmatched quote as
its last character.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Sven Köhler <remove-sven.koehler@gmail.com> |
|---|---|
| Date | 2013-04-24 11:22 +0300 |
| Message-ID | <atpj1nFn8eU1@mid.dfncis.de> |
| In reply to | #23601 |
On 04/24/2013 12:05 AM, Martin Gregorie wrote: > Actually, on Linux almost all the messing about with strings is done by > the shell that invokes the the command if the strings are enclosed in > double quotes. Use single quotes instead and the strings arrive at the > program ProcessBuilder is running with no modification at all. Here are > the results of using (1) double quoted strings and (2) single quoted > strings. I don't know what you mean. On Linux (or other UNIX-like operating systems), you specify the command line parameters as an array of strings when executing an external program. There is by definition no "messing about" with strings. Whatever syntax the shell uses to escape quotes and backslashes is irrelevant to ProcessBuilder, as it doesn't use the shell to start programs, but rather invokes some flavor of the exec function directly. Regards, Sven
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-04-24 20:22 +0000 |
| Message-ID | <kl9euk$leo$1@dont-email.me> |
| In reply to | #23617 |
On Wed, 24 Apr 2013 11:22:14 +0300, Sven Köhler wrote: > On 04/24/2013 12:05 AM, Martin Gregorie wrote: >> Actually, on Linux almost all the messing about with strings is done by >> the shell that invokes the the command if the strings are enclosed in >> double quotes. Use single quotes instead and the strings arrive at the >> program ProcessBuilder is running with no modification at all. Here are >> the results of using (1) double quoted strings and (2) single quoted >> strings. > > I don't know what you mean. On Linux (or other UNIX-like operating > systems), you specify the command line parameters as an array of strings > when executing an external program. There is by definition no "messing > about" with strings. Whatever syntax the shell uses to escape quotes and > backslashes is irrelevant to ProcessBuilder, as it doesn't use the shell > to start programs, but rather invokes some flavor of the exec function > directly. > It is not irrelevant if, as my test case does, you specify the ProcessBuilder arguments as part of a bash shell command. In these circumstances if you want ProcessBuilder to use exactly the argument content you wrote you must enclose the argument in single quotes to prevent the substitutions, etc the shell applies to unquoted words or to double-quoted arguments. If you do this you'll then see that neither the ProcessBuilder constructor nor the way ProcessBuilder passes the arguments to the program being called make any changes to the content of the arguments. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [next] | [standalone]
Page 2 of 5 — ← Prev page 1 [2] 3 4 5 Next page →
Back to top | Article view | comp.lang.java.programmer
csiph-web