31

On our Linux system we use named pipes for interprocess communication (a producer and a consumer).

In order to test the consumer (Java) code, I would like to implement (in Java) a dummy producer which writes to a named pipe which is connected to the consumer.

Now the test should also work in the Windows development environment. Thus I would like to know how to create a named pipe in Windows from Java. In Linux I can use mkfifo (called using Runtime.exec() ), but how should I do this on Windows?

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Philipp
  • 4,659
  • 9
  • 48
  • 69

6 Answers6

30

Use Named Pipes to Communicate Between Java and .Net Processes

Relevant part in the link

try {
  // Connect to the pipe
  RandomAccessFile pipe = new RandomAccessFile("\\\\.\\pipe\\testpipe", "rw");
  String echoText = "Hello word\n";
  // write to pipe
  pipe.write ( echoText.getBytes() );
  // read response
  String echoResponse = pipe.readLine();
  System.out.println("Response: " + echoResponse );
  pipe.close();
} catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}
Philipp
  • 4,659
  • 9
  • 48
  • 69
v01ver
  • 340
  • 3
  • 2
  • 4
    Does the code above work for someone? I have tried it on Windows 7 x64, Java 1.7.0_45 and it resulted `java.io.FileNotFoundException: \\.\pipe\testpipe (The system cannot find the file specified) at java.io.RandomAccessFile.open(Native Method) at java.io.RandomAccessFile.(RandomAccessFile.java:122)`. Should it be created forehand like mentioned [in this post](http://answers.microsoft.com/en-us/windows/forum/windows8_1-files/windows-81-enterprise-64-bit-running-java-jdk/f67d1302-905e-4511-ba1b-0888b259258a)? – dma_k Jun 08 '16 at 17:24
  • 9
    I got the answer to my question above: in Java it is not possible to create a named pipe (unless one uses [JNA](https://github.com/java-native-access/jna/blob/master/contrib/platform/test/com/sun/jna/platform/win32/Kernel32NamedPipeTest.java)), only to open an existing one (see [this answer](http://stackoverflow.com/a/2247022/267197) and [that post](https://cdimascio.wordpress.com/2014/01/11/named-pipes-with-java/)). Many thanks to answers below as well. – dma_k Jun 08 '16 at 18:28
  • 2
    @dma_k I get the same error. It seems that it is not possible to create a named pipe with Java but the code works with an existing pipe that was created in an other process (e.g. the .Net process in the linked example). – Michael Aug 11 '16 at 07:57
  • Sharing this so it doesn't bite someone else: `RandomAccessFile#getChannel` will not work with this. No data will be sent either way. Create a wrapper `ByteChannel` yourself that calls `read` and `write` on the underlying `RandomAccessFile`, and don't use its `getChannel`. – Aly Jan 03 '22 at 08:07
11

In windows, named pipes exist but they cannot be created as files in a writeable filesystem and there is no command line tool. They live in a special filesystem and can be created only by using the Win32 API.

Looks like you'll have to resort to native code, or switch from pipes to sockets for IPC - probably the best longterm solution, since it's much more portable.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
7

You can create named pipe using JNA library https://github.com/java-native-access/jna

It is clearly shown in the following test: https://github.com/java-native-access/jna/blob/master/contrib/platform/test/com/sun/jna/platform/win32/Kernel32NamedPipeTest.java

API of JNA wrapper is the same as Win32 hence you will be able to use all the features and power of named pipes on Windows.

jreznot
  • 2,694
  • 2
  • 35
  • 53
  • Indeed, this is possible with JNA library. Here is some functionality implemented in Kotlin: https://github.com/mikhail-dvorkin/pipesKt – Mikhail Dvorkin Aug 16 '23 at 15:41
2

It is very much possible to read and write to an existing named pipe in Java. You cannot, to my knowledge, create a named pipe in a Windows environment. Linux is a different story as named pipes can be created and consumed like files.

Relevant link on interacting with an existing pipe: http://v01ver-howto.blogspot.com/2010/04/howto-use-named-pipes-to-communicate.html

shellster
  • 1,091
  • 1
  • 10
  • 21
0

maybe could use cygwin named pipes--if all your processes are cygwin.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
  • In order to do this, you'd need Java on Cygwin. Seems pretty unlikely to me, though you might could wing it with one of the non-Sun JREs. – user314104 Feb 12 '12 at 05:55
0

We implemented some functionality including creating named pipes in Kotlin:

https://github.com/mikhail-dvorkin/pipesKt

There are methods for creating named pipes that work both in Windows and in Unix. We use JNA library.