Skip to content

Commit bc882e2

Browse files
authored
Work around Java emulators + WSL connectivity issues. (#2780)
1 parent ef28371 commit bc882e2

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Work around Java emulators + WSL connectivity issues.

src/emulator/controller.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,20 @@ import { FLAG_EXPORT_ON_EXIT_NAME } from "./commandUtils";
4141
import { fileExistsSync } from "../fsutils";
4242

4343
async function getAndCheckAddress(emulator: Emulators, options: any): Promise<Address> {
44-
const host = Constants.normalizeHost(
44+
let host = Constants.normalizeHost(
4545
options.config.get(Constants.getHostKey(emulator), Constants.getDefaultHost(emulator))
4646
);
4747

48+
if (host === "localhost" && utils.isRunningInWSL()) {
49+
// HACK(https://github.com/firebase/firebase-tools-ui/issues/332): Use IPv4
50+
// 127.0.0.1 instead of localhost. This, combined with the hack in
51+
// downloadableEmulators.ts, forces the emulator to listen on IPv4 ONLY.
52+
// The CLI (including the hub) will also consistently report 127.0.0.1,
53+
// causing clients to connect via IPv4 only (which mitigates the problem of
54+
// some clients resolving localhost to IPv6 and get connection refused).
55+
host = "127.0.0.1";
56+
}
57+
4858
const portVal = options.config.get(Constants.getPortKey(emulator), undefined);
4959
let port;
5060
let findAvailablePort = false;

src/emulator/downloadableEmulators.ts

+14
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,20 @@ function _getCommand(
168168

169169
const cmdLineArgs = baseCmd.args.slice();
170170

171+
if (
172+
baseCmd.binary === "java" &&
173+
utils.isRunningInWSL() &&
174+
(!args.host || !args.host.includes(":"))
175+
) {
176+
// HACK(https://github.com/firebase/firebase-tools-ui/issues/332): Force
177+
// Java to use IPv4 sockets in WSL (unless IPv6 address explicitly used).
178+
// Otherwise, Java will open a tcp6 socket (even if IPv4 address is used),
179+
// which handles both 4/6 on Linux but NOT IPv4 from the host to WSL.
180+
// This is a hack because it breaks all IPv6 connections as a side effect.
181+
// See: https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html
182+
cmdLineArgs.unshift("-Djava.net.preferIPv4Stack=true"); // first argument
183+
}
184+
171185
const logger = EmulatorLogger.forEmulator(emulator);
172186
Object.keys(args).forEach((key) => {
173187
if (!baseCmd.optionalArgs.includes(key)) {

src/utils.ts

+8
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,11 @@ export function datetimeString(d: Date): string {
478478
export function isCloudEnvironment() {
479479
return !!process.env.CODESPACES;
480480
}
481+
482+
/**
483+
* Indicates whether or not this process is likely to be running in WSL.
484+
* @return true if we're likely in WSL, false otherwise
485+
*/
486+
export function isRunningInWSL(): boolean {
487+
return !!process.env.WSL_DISTRO_NAME;
488+
}

0 commit comments

Comments
 (0)