2

I've got an example Java application that requires an HTTP Proxy to be specified in some environments.

When I try running this using the argument as suggested on the Oracle website in CMD (Command Prompt) it works fine.

E:\>java -Dhttp.proxyHost=http://proxy.example.com -jar myJAR.jar
System properties...
[...]
http.proxyHost=http://proxy.example.com

You can see that the application has been run, and when listing the system properties it's correctly received the http.proxyHost property.

However, when I run this from Powershell, I get the following:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS E:\> java -Dhttp.proxyHost=http://proxy.example.com -jar myJAR.jar
Error: Could not find or load main class .proxyHost=http:..proxy.example.com

Here it appears some kind of breaking has occurred around the first "." and from then on it's treated the rest as another argument.

If the argument is quoted - e.g. -D"http.proxyHost"=http://proxy.example.com - then it works fine in Powershell.

Can anyone explain this behavior, please?

Pushprajsinh Chudasama
  • 7,772
  • 4
  • 20
  • 43
Jakg
  • 922
  • 12
  • 39
  • Powershell will try to parse your input parameters to the program so to avoid that you need to wrap them in double quotes so that instead of parsing them they are passed as it is to the executable program – DevX Mar 02 '20 at 11:32
  • @DevX do you have a source for this, please? – Jakg Mar 02 '20 at 11:36
  • 1
    See [Call Operator](https://ss64.com/ps/call.html) for how to call external programs from PowerShell. – AdminOfThings Mar 02 '20 at 11:49
  • @Jakg I did some search a while back when I had the same problem with java and found [this](https://superuser.com/questions/731638/command-line-parameters-in-powershell) on SuperUser. May not be an exact source you were looking for but it did help me understand a few things – DevX Mar 02 '20 at 12:00
  • The comment from @AdminofThings is the answer. The Call Operator prevents inappropriate parsing of the arguments to java. – Walter Mitty Mar 02 '20 at 12:06
  • @Jakg, see [About Parsing](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-7) and [Command Syntax](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_command_syntax?view=powershell-7). `-` tells PowerShell a parameter is coming and everything after it is treated as an expandable string. `.` is the member access operator in PowerShell. So it needs to be escaped or you need to tell Posh to stop parsing --> `java --% -Dhttp.proxyHost=http://proxy.example.com -jar myJAR.jar` – AdminOfThings Mar 02 '20 at 12:08
  • @Jakg, also, the fact that you started your execution line with `java`, PowerShell goes into argument parsing mode. You can see on the links I provided examples of when the different parsing modes are activated. – AdminOfThings Mar 02 '20 at 12:15
  • @AdminOfThings, while `--%` is an effective _workaround_ - albeit one with major side effects in general - the behavior is a _bug_: since the unquoted token isn't a variable reference or expression, it should be treated like an _expandable string_ - `.` should have _no_ special meaning in this context; a side-effect-free workaround is to quote the `.` individually as `'.'` – mklement0 Mar 02 '20 at 15:33
  • No, @WalterMitty: whether or not you use `&` (the call operator) makes no difference with respect to argument parsing. – mklement0 Mar 02 '20 at 15:34

2 Answers2

1

man about_Parsing

try running from powershell using --% parameter:

java --% -Dhttp.proxyHost=http://proxy.example.com -jar myJAR.jar
con
  • 5,767
  • 8
  • 33
  • 62
Sergey Shu
  • 11
  • 1
1

Unfortunately, you're seeing a bug in PowerShell, present up to at least v7.3.6 (current as of this writing):

Something that looks like a parameter to PowerShell is broken into two arguments at the . (period) - even though the argument should simply be passed through, given that an external program is called - see GitHub issue #6291; in your case, -Dhttp.proxyHost=http://proxy.example.com is unexpectedly passed as
-Dhttp .proxyHost=http://proxy.example.com (note the space before the .)

Workarounds:

  • `-escape the initial - (or quote the . character individually ('.') or quote the whole argument):

    java `-Dhttp.proxyHost=http://proxy.example.com -jar myJAR.jar
    
  • Alternatively, as shown in Sergey Shu's answer, use --%, the stop-parsing symbol, to force PowerShell to pass all arguments through without applying PowerShell's usual parsing rules.

    • Caveat: Use of --% has major side effects, notably the inability to use variable references in the command and the inability to apply redirections - see this answer for details.
mklement0
  • 382,024
  • 64
  • 607
  • 775