Ion Juvina

42 papers B 6Journal 11Unranked 23
YearRankTypeTitle / Venue / Authors
2025 conf
CAI
Amy Summerville, Louis Martí, Ion Juvina, B. Locke Welborn, Cara Leigh Widmer, Alice Leung
2023 ed.
RoCHI
Teodor Stefanut, Ion Juvina, Dorian Gorgan
2023 B conf
CogSci
Jarean Carson, Preston S. Menke, Chi Hang Wong, Kristin M. Kindell, Ion Juvina
2023 J jnl
Top. Cogn. Sci.
Jarean Carson, Ion Juvina, Kevin O'Neill, Chi Hang Wong, Preston S. Menke, Kristin M. Kindell, Erin Harmon
2023 conf
RoCHI
Chi Hang Wong, Ion Juvina, Paul-Stefan Popescu
2023 J jnl
J. Web Semant.
Cara Leigh Widmer, Md. Kamruzzaman Sarker, Srikanth Nadella, Joshua Fiechter, Ion Juvina, Brandon S. Minnery, Pascal Hitzler, Joshua Schwartz, Michael L. Raymer
2022 conf
RoCHI
Ion Juvina, Kevin O'Neill
2022 conf
RoCHI (Selected Papers)
Ion Juvina, Kevin O'Neill, Jarean Carson, Preston S. Menke, Chi Hang Wong, Hannah McNett, Gabriel Holsinger
2022 J jnl
CoRR
Cara Leigh Widmer, Md. Kamruzzaman Sarker, Srikanth Nadella, Joshua Fiechter, Ion Juvina, Brandon S. Minnery, Pascal Hitzler, Joshua Schwartz, Michael L. Raymer
2022 B conf
CogSci
Alexander Hough, Ion Juvina
2020 J jnl
J. Cogn. Neurosci.
Jeffrey Nador, Assaf Harel, Ion Juvina, Brandon S. Minnery
2020 conf
KGSWC
Md. Kamruzzaman Sarker, Joshua Schwartz, Pascal Hitzler, Lu Zhou, Srikanth Nadella, Brandon S. Minnery, Ion Juvina, Michael L. Raymer, William R. Aue
2019 conf
COGSAT@AAAI Fall Symposium
Alexander Hough, Othalia Larue, Ion Juvina
2019 J jnl
Top. Cogn. Sci.
Christopher W. Myers, Joseph Houpt, Ion Juvina
2019 conf
COGSAT@AAAI Fall Symposium
Ion Juvina, Othalia Larue, Colin Widmer, Subhashini Ganapathy, Srikanth Nadella, Brandon S. Minnery
2019 J jnl
ACM Trans. Interact. Intell. Syst.
Ion Juvina, Michael G. Collins, Othalia Larue, William G. Kennedy, Ewart de Visser, Celso De Melo
2018 conf
BICA
Othalia Larue, Robert West, Paul S. Rosenbloom, Christopher L. Dancy, Alexei V. Samsonovich, Dean Petters, Ion Juvina
2018 B conf
CogSci
Ion Juvina, Jeffrey Nador, Othalia Larue, Randall Green, Assaf Harel, Brandon S. Minnery
2018 J jnl
Cogn. Syst. Res.
Ion Juvina, Othalia Larue, Alexander Hough
2017 B conf
CogSci
Othalia Larue, Alexander Hough, Ion Juvina
2017 B conf
CogSci
Ion Juvina, Jeffrey Nador, Othalia Larue, Randall Green, Brandon S. Minnery, Assaf Harel
2016 conf
SBP-BRiMS
Michael G. Collins, Ion Juvina, Kevin A. Gluck
2015 conf
HCI (15)
Priya Ganapathy, Ion Juvina, Tejaswi Tamminedi, Gautam Kunapuli, Matt Sherwood, Mohd Saif Usmani
2015 conf
HCI (15)
Ion Juvina, Priya Ganapathy, Matt Sherwood, Mohd Saif Usmani, Gautam Kunapuli, Tejaswi Tamminedi, Nasser H. Kashou
2015 conf
HCI (15)
Othalia Larue, Ion Juvina, Gary Douglas, Albert Simmons
2012 B conf
CogSci
Ion Juvina, Christian Lebiere, Cleotilde Gonzalez, Muniba Saleem
2012 conf
SBP
Ion Juvina, Christian Lebiere, Cleotilde Gonzalez, Muniba Saleem
2011 conf
SBP
Ion Juvina, Christian Lebiere, Jolie M. Martin, Cleotilde Gonzalez
2011 J jnl
Top. Cogn. Sci.
Ion Juvina
2011 conf
BICA
Ion Juvina, James A. Grange, Christian Lebiere
2011 J jnl
Games
Ion Juvina, Christian Lebiere, Jolie M. Martin, Cleotilde Gonzalez
2011 conf
HCI (21)
Jolie M. Martin, Ion Juvina, Christian Lebiere, Cleotilde Gonzalez
2007 conf
Hypertext
Mari Carmen Puerta Melguizo, Herre van Oostendorp, Ion Juvina
2007 J jnl
Int. J. Hum. Comput. Stud.
Herre van Oostendorp, Ion Juvina
2006
Ion Juvina
2006 J jnl
Univers. Access Inf. Soc.
Ion Juvina, Herre van Oostendorp
2005 conf
BCS HCI
Ion Juvina, Herre van Oostendorp
2005 conf
User Modeling
Ion Juvina, Eelco Herder
2004 conf
User Interfaces for All
Ion Juvina, Herre van Oostendorp
2003 conf
CSCL
Herre van Oostendorp, Ion Juvina
2002 conf
TAMODIA
Ion Juvina, Stefan Trausan-Matu, Gheorghe Iosif, Gerrit C. van der Veer, Ana-Maria Marhan, Cristina Chisalita
2002 conf
TAMODIA
Stefan Trausan-Matu, Gheorghe Iosif, Ion Juvina, Alina Marhan
redb/extractors/decompiler/apk/jadx_wrapper.py
← Index redb/extractors/decompiler/apk/jadx_wrapper.py python
"""JADX decompiler subprocess wrapper.

Manages JADX subprocess execution for Java decompilation,
following the CAPA extractor subprocess pattern.
"""

import os
import re
import signal
import subprocess
from typing import Dict, Optional


class JADXDecompiler:
    """Subprocess wrapper for JADX Java decompilation."""

    def __init__(self, jadx_path: str = None, timeout: int = None, log=None):
        self.jadx_path = jadx_path or os.getenv("JADX_PATH", "jadx")
        self.timeout = timeout or int(os.getenv("JADX_TIMEOUT", "300"))
        self.log = log

    def decompile(self, apk_path: str, output_dir: str) -> bool:
        """Run JADX decompilation on an APK file.

        Returns True on success, False on failure.
        """
        cmd = [
            self.jadx_path,
            "--no-res",
            "--no-imports",
            "--threads-count", "2",
            "--output-dir", output_dir,
            apk_path,
        ]

        try:
            process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                preexec_fn=os.setsid,
            )

            try:
                stdout, stderr = process.communicate(timeout=self.timeout)
                if process.returncode != 0:
                    if self.log:
                        self.log.warning(
                            f"JADX returned non-zero exit code {process.returncode}: "
                            f"{stderr[:500] if stderr else 'no stderr'}"
                        )
                    # JADX may still produce partial output on non-zero exit
                    return os.path.isdir(os.path.join(output_dir, "sources"))
                return True

            except subprocess.TimeoutExpired:
                if self.log:
                    self.log.error(
                        f"JADX timed out after {self.timeout}s"
                    )
                # Kill the process group
                try:
                    os.killpg(os.getpgid(process.pid), signal.SIGTERM)
                    process.wait(timeout=3)
                except (ProcessLookupError, subprocess.TimeoutExpired):
                    try:
                        os.killpg(os.getpgid(process.pid), signal.SIGKILL)
                    except ProcessLookupError:
                        pass
                return False

        except FileNotFoundError:
            if self.log:
                self.log.error(
                    f"JADX not found at '{self.jadx_path}'. "
                    "Install JADX or set JADX_PATH env var."
                )
            return False
        except Exception as e:
            if self.log:
                self.log.error(f"JADX execution error: {e}")
            return False

    def parse_java_methods(self, output_dir: str) -> Dict[str, str]:
        """Parse JADX output into per-method Java source.

        Returns dict keyed by 'package.ClassName.methodName(ParamType1, ParamType2)'.
        """
        sources_dir = os.path.join(output_dir, "sources")
        if not os.path.isdir(sources_dir):
            return {}

        methods = {}
        for root, _dirs, files in os.walk(sources_dir):
            for fname in files:
                if not fname.endswith(".java"):
                    continue
                fpath = os.path.join(root, fname)
                try:
                    with open(fpath, "r", encoding="utf-8", errors="replace") as f:
                        content = f.read()

                    # Derive the fully qualified class name from file path
                    rel_path = os.path.relpath(fpath, sources_dir)
                    class_fqn = rel_path.replace(os.sep, ".").replace("/", ".")
                    if class_fqn.endswith(".java"):
                        class_fqn = class_fqn[:-5]

                    file_methods = self._extract_methods_from_java(
                        content, class_fqn
                    )
                    methods.update(file_methods)

                except Exception:
                    continue

        return methods

    def _extract_methods_from_java(
        self, source: str, class_fqn: str
    ) -> Dict[str, str]:
        """Extract individual methods from a Java source file.

        Uses brace-depth tracking to find method boundaries.
        """
        methods = {}
        lines = source.split("\n")
        i = 0

        while i < len(lines):
            line = lines[i]
            match = self._is_method_declaration(line)
            if match:
                method_name, param_types = match
                # Track brace depth to find method end
                start_line = i
                brace_depth = 0
                found_open = False

                for j in range(i, len(lines)):
                    for ch in lines[j]:
                        if ch == "{":
                            brace_depth += 1
                            found_open = True
                        elif ch == "}":
                            brace_depth -= 1

                    if found_open and brace_depth == 0:
                        method_body = "\n".join(lines[start_line : j + 1])
                        key = f"{class_fqn}.{method_name}({param_types})"
                        methods[key] = method_body
                        i = j + 1
                        break
                else:
                    i += 1
            else:
                i += 1

        return methods

    # Regex for method declarations (not constructors, not class/interface decl)
    _METHOD_DECL_RE = re.compile(
        r"^\s*(?:(?:public|private|protected|static|final|synchronized|"
        r"native|abstract|strictfp)\s+)*"
        r"(?:[\w<>\[\]?.]+\s+)"  # return type
        r"(\w+)"  # method name
        r"\s*\(([^)]*)\)"  # parameters
        r"(?:\s*throws\s+[\w.,\s]+)?"
        r"\s*\{"
    )

    def _is_method_declaration(self, line: str) -> Optional[tuple]:
        """Check if a line is a method declaration.

        Returns (method_name, param_types_str) or None.
        """
        m = self._METHOD_DECL_RE.match(line)
        if not m:
            return None

        method_name = m.group(1)
        params_raw = m.group(2).strip()

        # Skip class-level blocks
        if method_name in ("if", "for", "while", "switch", "try", "catch"):
            return None

        # Extract just the type names from parameters
        if not params_raw:
            return (method_name, "")

        param_types = []
        for param in params_raw.split(","):
            param = param.strip()
            if not param:
                continue
            parts = param.split()
            # Last non-annotation token before the variable name is the type
            # Simple heuristic: type is second-to-last, name is last
            if len(parts) >= 2:
                param_types.append(parts[-2])
            elif len(parts) == 1:
                param_types.append(parts[0])

        return (method_name, ", ".join(param_types))