0

How do I pass in the unix line separator to Java.exe on Windows.

I tried this

-Dline.separator=\n

it doesn't work.

I am on Windows, I run cmd.exe, then I run a bat file.
I want to pass in the unix line separator.

Does it matter if I run the bat file with cmd.exe or with power shell.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • 1
    Why you want to do this – Jens Aug 24 '22 at 13:46
  • @Jens Because maven (maven-resources-plugin) generates my resource files with Windows line separator, I want them to be with unix line separator. So I found somewhere that this is the fix I should do. – peter.petrov Aug 24 '22 at 13:47
  • Have you tried to put it in single or double quotes? – Jens Aug 24 '22 at 13:51
  • [see also](https://stackoverflow.com/q/13288030/592355) – xerx593 Aug 24 '22 at 13:54
  • And "maven-resources-plugin generates.." is somewhat strange, because it should "only copy" and "little filter"... under circumstances – xerx593 Aug 24 '22 at 13:56
  • ..and the files under "resources" are normally managed by version control (auto-crlf!?) – xerx593 Aug 24 '22 at 13:59
  • Yes, I am starting to think now it is related to git. I am on a new laptop so... That might be related – peter.petrov Aug 24 '22 at 15:09
  • As @xerx593 says, resource files are seldom "generated" during builds - they are *copied*. I'm not sure why it matters though, as rarely does software get confused by platform-specific line separators – g00se Aug 24 '22 at 15:32
  • Your git client can try and convert line endings from what is in the repo to what the local OS normally uses. This is often a bad idea. Check out settings such as ``core.autocrlf`` which tells git not to touch line endings as it pulls down code. – JohnXF Aug 24 '22 at 16:14
  • I could not find a way to override from commandline, but you can implement cross platform line endings with [PrintWriter override](https://stackoverflow.com/questions/63144771/how-can-i-force-java-stdout-on-windows-to-use-the-n-line-seperator/63149515#63149515). – DuncG Aug 24 '22 at 17:38
  • @JohnXF I know these settings, I never understood which one to use exactly. But my question still stands as is. I am curious how to pass that \n from the Windows cmd prompt. – peter.petrov Aug 24 '22 at 18:38
  • @DuncG I don't want to implement anything. I just want to pass a value for this property to the JVM. – peter.petrov Aug 24 '22 at 19:15

1 Answers1

3

After a bit of investigation ... you do set the value by passing an option like -Dline.separator=X on the command line, but it is important how and where you pass it. Firstly, you must pass the property before the class (as a parameter to the java executable) otherwise it is a parameter passed to the running program and thus not actually setting the 'environment' property.

Take this simple class as an example:

public class TestClass {
    public static void main(String[] args) {
        System.out.printf("property test.value [%s]  property line.separator [%s]",
                System.getProperty("test.value"), System.getProperty("line.separator") );
    }
}

On Windows Powershell, you need to execute like so ...

PS C:\> java -cp target\classes -D"line.separator=4" TestClass  -D"test.value=3"
property test.value [null]  property line.separator [4]

You see the line.separator value is set but the test.class value is not. On Windows you needed to double-quote the property names that are arguments to the java executable.

Passing both as parameters to the java program ...

PS C:\> java -cp target\classes -D"test.value=3" -D"line.separator=4" TestClass
property test.value [3]  property line.separator [4]

... to see the correct values received by the program.

To pass a newline, passing -D"line.separator=\n" does not work as the \n is treated as a string by Powershell so you must pass the Powershell notation for a newline - [`n] - to actually get the newline to the java program. eg:

PS C:\> java -cp target\classes -D"test.value=3" -D"line.separator=`n" TestClass
property test.value [3]  property line.separator [
]

Above you see an actual newline used in the output.

On unix the syntax is a bit different. You don't need to double-quote the property names but you still need to pass the newline character in a way that causes the shell to actually pass a newline.

Firstly, if we just pass a \n we see it is passed verbatim:

$ java -cp target/classes/ -Dtest.value=3 -Dline.separator='\n' TestClass
property test.value [3]  property line.separator [\n]

But if we tell the shell to process that string it will convert it into a newline:

$ java -cp target/classes/ -Dtest.value=3 -Dline.separator=$'\n' TestClass
property test.value [3]  property line.separator [
]

I'm not an expert in the ins and outs of shell scripting, but I can see there appears to be a few ways to pass a newline character depending on your OS and shell. To your specific ask about Windows and cmd, there is yet more fun. This question gives me the example script I need to run my sample and get a newline output.

I created a bat script called runjava.bat to run the java, and define the newline as a variable which is then passed as the parameter.

setlocal EnableDelayedExpansion
(set \n=^
%=Do not remove this line=%
)

echo Line1!\n!Line2
java -cp target\classes -Dtest.value=3 -Dline.separator=!\n! TestClass

Here I run the script and you can see the output has a newline in it.

c:\>.\runjava.bat

c:\>setlocal EnableDelayedExpansion

c:\>(set \n=
 )

c:\>echo Line1!\n!Line2
Line1
Line2

c:\>java -cp target\classes -Dtest.value=3 -Dline.separator=!\n! TestClass
property test.value [3]  property line.separator [
]

To summarise ... you can override the line.separator property but you will have to get the syntax just right!

JohnXF
  • 972
  • 9
  • 22
  • Thanks. Yes, I know the -D params have to be before the class name, that's clear to me. But in Windows cmd prompt, can we do it without having a batch file and without setting variable in it? Can we do it with just a one line, i.e. one command `java -cp target\classes -Dtest.value=3 -Dline.separator=??? TestClass` I was surprised yesterday that such a simple thing is so difficult in Windows cmd prompt. – peter.petrov Aug 25 '22 at 12:26
  • I too was surprised to not be able to pass the newline in a single command, and I could not find any answers to how to do it. You have tagged this question with ``maven`` and ``java`` but an answer to passing newline as part of a DOS/Windows command is more likely to be forthcoming from a different audience so perhaps open a direct question with more targetted tags (if not already asked?). – JohnXF Aug 25 '22 at 13:24
  • Thanks. OK, no... I just updated the tags. Anyway, thanks for your detailed answer. – peter.petrov Aug 26 '22 at 14:45