Skip to content

JavaAccessBridge

Helper for enabling and querying Java Access Bridge - required for Java Swing/AWT automation.


JavaAccessBridge

Utilities for enabling and checking the Java Access Bridge.

Source code in src\dolphin_desktop\_java.py
class JavaAccessBridge:
    """Utilities for enabling and checking the Java Access Bridge."""

    @staticmethod
    def is_enabled() -> bool:
        """Return True if Java Access Bridge appears to be active."""
        import winreg  # type: ignore[import-untyped]

        # Check the Accessibility ATs registry key for jabswitch
        try:
            key = winreg.OpenKey(
                winreg.HKEY_CURRENT_USER,
                r"Software\Microsoft\Windows NT\CurrentVersion\Accessibility\ATs",
            )
            with key:
                i = 0
                while True:
                    try:
                        name, _value, _type = winreg.EnumValue(key, i)
                        if "jabswitch" in name.lower() or "jab" in name.lower():
                            return True
                        i += 1
                    except OSError:
                        break
        except OSError:
            pass

        # Check the Configuration value (set by jabswitch /enable on modern JDK)
        try:
            key = winreg.OpenKey(
                winreg.HKEY_CURRENT_USER,
                r"Software\Microsoft\Windows NT\CurrentVersion\Accessibility",
            )
            with key:
                try:
                    val, _ = winreg.QueryValueEx(key, "Configuration")
                    low = val.lower()
                    if "javaaccessbridge" in low or "oracle_javaaccessbridge" in low:
                        return True
                except OSError:
                    pass
        except OSError:
            pass

        # Fallback: check for windowsaccessbridge-64.dll in common locations
        java_home = JavaAccessBridge.java_home()
        if java_home:
            for name in ("WindowsAccessBridge-64.dll", "windowsaccessbridge-64.dll"):
                if os.path.isfile(os.path.join(java_home, "bin", name)):
                    return True

        windir = os.environ.get("WINDIR", r"C:\Windows")
        for sub in ("SysWOW64", "System32"):
            for name in ("WindowsAccessBridge-64.dll", "windowsaccessbridge-64.dll"):
                if os.path.isfile(os.path.join(windir, sub, name)):
                    return True

        return False

    @staticmethod
    def enable() -> None:
        """Run jabswitch.exe /enable; raises RuntimeError on failure."""
        java_home = JavaAccessBridge.java_home()
        jabswitch = "jabswitch.exe"
        if java_home:
            candidate = os.path.join(java_home, "bin", "jabswitch.exe")
            if os.path.isfile(candidate):
                jabswitch = candidate
        try:
            result = subprocess.run(
                [jabswitch, "/enable"],
                capture_output=True,
                timeout=15,
            )
        except FileNotFoundError as exc:
            raise RuntimeError(
                "jabswitch.exe not found — ensure a JRE/JDK with Java Access Bridge is "
                "installed and jabswitch.exe is on PATH or JAVA_HOME is set."
            ) from exc
        if result.returncode != 0:
            stderr = result.stderr.decode(errors="replace")
            raise RuntimeError(f"jabswitch.exe /enable failed (exit {result.returncode}): {stderr}")

    @staticmethod
    def ensure_enabled() -> None:
        """Enable Java Access Bridge only if it is not already enabled."""
        if not JavaAccessBridge.is_enabled():
            JavaAccessBridge.enable()

    @staticmethod
    def java_home() -> str | None:
        """Return the JRE/JDK home directory, or None if not found."""
        env_home = os.environ.get("JAVA_HOME")
        if env_home and os.path.isdir(env_home):
            return env_home

        import winreg  # type: ignore[import-untyped]

        for root in (winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER):
            for sub in (
                r"SOFTWARE\JavaSoft\Java Runtime Environment",
                r"SOFTWARE\JavaSoft\JRE",
                r"SOFTWARE\JavaSoft\JDK",
            ):
                try:
                    key = winreg.OpenKey(root, sub)
                    with key:
                        try:
                            current, _ = winreg.QueryValueEx(key, "CurrentVersion")
                            ver_key = winreg.OpenKey(key, current)
                            with ver_key:
                                home, _ = winreg.QueryValueEx(ver_key, "JavaHome")
                                if home and os.path.isdir(home):
                                    return home
                        except OSError:
                            pass
                except OSError:
                    pass

        try:
            result = subprocess.run(
                ["where.exe", "java"],
                capture_output=True,
                timeout=5,
            )
            if result.returncode == 0:
                java_exe = result.stdout.decode(errors="replace").splitlines()[0].strip()
                home = os.path.dirname(os.path.dirname(java_exe))
                if os.path.isdir(home):
                    return home
        except Exception:
            pass

        return None

is_enabled staticmethod

is_enabled() -> bool

Return True if Java Access Bridge appears to be active.

Source code in src\dolphin_desktop\_java.py
@staticmethod
def is_enabled() -> bool:
    """Return True if Java Access Bridge appears to be active."""
    import winreg  # type: ignore[import-untyped]

    # Check the Accessibility ATs registry key for jabswitch
    try:
        key = winreg.OpenKey(
            winreg.HKEY_CURRENT_USER,
            r"Software\Microsoft\Windows NT\CurrentVersion\Accessibility\ATs",
        )
        with key:
            i = 0
            while True:
                try:
                    name, _value, _type = winreg.EnumValue(key, i)
                    if "jabswitch" in name.lower() or "jab" in name.lower():
                        return True
                    i += 1
                except OSError:
                    break
    except OSError:
        pass

    # Check the Configuration value (set by jabswitch /enable on modern JDK)
    try:
        key = winreg.OpenKey(
            winreg.HKEY_CURRENT_USER,
            r"Software\Microsoft\Windows NT\CurrentVersion\Accessibility",
        )
        with key:
            try:
                val, _ = winreg.QueryValueEx(key, "Configuration")
                low = val.lower()
                if "javaaccessbridge" in low or "oracle_javaaccessbridge" in low:
                    return True
            except OSError:
                pass
    except OSError:
        pass

    # Fallback: check for windowsaccessbridge-64.dll in common locations
    java_home = JavaAccessBridge.java_home()
    if java_home:
        for name in ("WindowsAccessBridge-64.dll", "windowsaccessbridge-64.dll"):
            if os.path.isfile(os.path.join(java_home, "bin", name)):
                return True

    windir = os.environ.get("WINDIR", r"C:\Windows")
    for sub in ("SysWOW64", "System32"):
        for name in ("WindowsAccessBridge-64.dll", "windowsaccessbridge-64.dll"):
            if os.path.isfile(os.path.join(windir, sub, name)):
                return True

    return False

enable staticmethod

enable() -> None

Run jabswitch.exe /enable; raises RuntimeError on failure.

Source code in src\dolphin_desktop\_java.py
@staticmethod
def enable() -> None:
    """Run jabswitch.exe /enable; raises RuntimeError on failure."""
    java_home = JavaAccessBridge.java_home()
    jabswitch = "jabswitch.exe"
    if java_home:
        candidate = os.path.join(java_home, "bin", "jabswitch.exe")
        if os.path.isfile(candidate):
            jabswitch = candidate
    try:
        result = subprocess.run(
            [jabswitch, "/enable"],
            capture_output=True,
            timeout=15,
        )
    except FileNotFoundError as exc:
        raise RuntimeError(
            "jabswitch.exe not found — ensure a JRE/JDK with Java Access Bridge is "
            "installed and jabswitch.exe is on PATH or JAVA_HOME is set."
        ) from exc
    if result.returncode != 0:
        stderr = result.stderr.decode(errors="replace")
        raise RuntimeError(f"jabswitch.exe /enable failed (exit {result.returncode}): {stderr}")

ensure_enabled staticmethod

ensure_enabled() -> None

Enable Java Access Bridge only if it is not already enabled.

Source code in src\dolphin_desktop\_java.py
@staticmethod
def ensure_enabled() -> None:
    """Enable Java Access Bridge only if it is not already enabled."""
    if not JavaAccessBridge.is_enabled():
        JavaAccessBridge.enable()

java_home staticmethod

java_home() -> str | None

Return the JRE/JDK home directory, or None if not found.

Source code in src\dolphin_desktop\_java.py
@staticmethod
def java_home() -> str | None:
    """Return the JRE/JDK home directory, or None if not found."""
    env_home = os.environ.get("JAVA_HOME")
    if env_home and os.path.isdir(env_home):
        return env_home

    import winreg  # type: ignore[import-untyped]

    for root in (winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER):
        for sub in (
            r"SOFTWARE\JavaSoft\Java Runtime Environment",
            r"SOFTWARE\JavaSoft\JRE",
            r"SOFTWARE\JavaSoft\JDK",
        ):
            try:
                key = winreg.OpenKey(root, sub)
                with key:
                    try:
                        current, _ = winreg.QueryValueEx(key, "CurrentVersion")
                        ver_key = winreg.OpenKey(key, current)
                        with ver_key:
                            home, _ = winreg.QueryValueEx(ver_key, "JavaHome")
                            if home and os.path.isdir(home):
                                return home
                    except OSError:
                        pass
            except OSError:
                pass

    try:
        result = subprocess.run(
            ["where.exe", "java"],
            capture_output=True,
            timeout=5,
        )
        if result.returncode == 0:
            java_exe = result.stdout.decode(errors="replace").splitlines()[0].strip()
            home = os.path.dirname(os.path.dirname(java_exe))
            if os.path.isdir(home):
                return home
    except Exception:
        pass

    return None

Usage

from dolphin_desktop import JavaAccessBridge

# Check status
print(f"JAB enabled: {JavaAccessBridge.is_enabled()}")
print(f"Java home:   {JavaAccessBridge.java_home()}")

# Ensure enabled (idempotent - safe to call before every Java test)
JavaAccessBridge.ensure_enabled()

JABLocator

When Window.get_by_*() is called on a Java window (class_name="SunAwtFrame"), Dolphin returns a JABLocator instead of the standard Locator. The high-level API is similar:

from dolphin_desktop import Desktop

desktop = Desktop()
app = desktop.launch_java("java -jar SwingApp.jar")
win = app.window(class_name="SunAwtFrame")

# win.get_by_role() returns JABLocator automatically
win.get_by_role("push button", name="OK").click()
win.get_by_role("text", name="Username").type_text("admin")

See the Java guide for the full role mapping table.