You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法通过Java代码启动Appium服务及import语法错误问题求助

解决Appium启动时的SyntaxError: Cannot use import statement outside a module错误

这个错误很常见,原因是你指定的appium/lib/appium.js是Appium v2+使用的ES模块文件(用了import语法),但Node.js默认以CommonJS模式运行,无法直接识别ES模块的语法。下面是几个靠谱的解决办法:

1. 使用Appium官方提供的正确入口文件

Appium v2+的核心代码已经迁移到ES模块,官方的启动入口不是lib/appium.js,而是build/main.js。你只需要修改withAppiumJS指向的文件路径即可:

修改后的Option 1代码

public static void runAppiumService(String portNumber) {
    // Build parameters for appium server:
    AppiumServiceBuilder appiumServiceBuilder = new AppiumServiceBuilder();
    appiumServiceBuilder.usingPort(Integer.parseInt(portNumber))
            .withIPAddress("127.0.0.1")
            // 替换为Appium v2的正确入口文件
            .withAppiumJS(new File("C:\\Users\\Ritesh Mittal\\AppData\\Roaming\\npm\\node_modules\\appium\\build\\main.js"))
            .withArgument(GeneralServerFlag.SESSION_OVERRIDE)
            .withLogFile(new File(System.getProperty("user.dir") + "/target/resources/appium_server_logs_" + Thread.currentThread().getId()));
    AppiumDriverLocalService service = AppiumDriverLocalService.buildService(appiumServiceBuilder);
    service.start();
}

修改后的Option 2代码

另外注意:Option 2里不要把会话的DesiredCapabilities传给withCapabilities,这个方法是用来配置服务启动参数的,不是会话参数。同时替换正确的Appium入口:

DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.DEVICE_NAME, deviceName);
dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
dc.setCapability(MobileCapabilityType.APP, System.getProperty("user.dir")+"/src/test/resources/apps/CRMNextNative 6.29.0-release_screenshot_enabled.apk");
dc.setCapability("automationName","UiAutomator2");
dc.setCapability("appPackage", "com.crmnextmobile.crmnextofflineplay");
dc.setCapability("appActivity", "com.crmnextmobile.crmnextofflineplay.qr.QrScannerActivity");
dc.setCapability("enforceAppInstall", true); // 修正拼写错误:原代码是enforceAppInsall

URL url = new URL("http://127.0.0.1:"+portNumber+"/wd/hub");
AppiumDriverLocalService service;
service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder()
        .usingPort(Integer.parseInt(portNumber))
        .usingDriverExecutable(new File("C:\\Program Files\\nodejs\\node.exe"))
        // 替换为正确的入口文件
        .withAppiumJS(new File("C:\\Users\\Ritesh Mittal\\AppData\\Roaming\\npm\\node_modules\\appium\\build\\main.js"))
        .withArgument(GeneralServerFlag.RELAXED_SECURITY)
        .withArgument(GeneralServerFlag.SESSION_OVERRIDE)
        .withArgument(GeneralServerFlag.LOG_LEVEL, "error"));
        // 移除这里的.withCapabilities(dc),会话capabilities在创建Driver时传入
service.start();
logger.info("Appium started ......");
Thread.sleep(10000);
driver = new AppiumDriver(url,dc);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
System.out.println("CRMNext automation start..");

2. 更简化的方式:依赖全局安装的Appium

如果你已经通过npm install -g appium全局安装了Appium,可以不用手动指定withAppiumJS和usingDriverExecutable,AppiumServiceBuilder会自动找到系统中的Appium命令,代码会更简洁:

AppiumDriverLocalService service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder()
        .usingPort(Integer.parseInt(portNumber))
        .withIPAddress("127.0.0.1")
        .withArgument(GeneralServerFlag.RELAXED_SECURITY)
        .withArgument(GeneralServerFlag.SESSION_OVERRIDE)
        .withArgument(GeneralServerFlag.LOG_LEVEL, "error"));
service.start();

额外注意事项

  • 确认你的Appium版本:如果是v1.x,入口确实是lib/appium.js,但v2.x必须用build/main.js,可以通过appium -v命令查看版本;
  • 检查端口占用:启动服务前确保指定的端口没有被其他进程占用,可以用netstat -ano | findstr :<你的端口号>命令排查;
  • 拼写错误:你的Option 2里把enforceAppInstall拼写成了enforceAppInsall,这个会导致capability不生效,已经帮你修正了。

内容的提问来源于stack exchange,提问作者mittalri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:58:12