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

Android集成MS Graph SDK报XMLInputFactory.newFactory方法不存在错误

问题描述

com.fasterxml.jackson.dataformat包下的XmlFactory类是Java版微软MS Graph SDK的传递依赖,调用SDK实现邮件发送功能时抛出运行时错误:

Caused by: java.lang.NoSuchMethodError: No static method newFactory(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljavax/xml/stream/XMLInputFactory; in class Ljavax/xml/stream/XMLInputFactory; or its super classes

经Gradle依赖树排查,项目加载的XMLInputFactory、XMLOutputFactory来自旧版stax:stax-api:1.0.1,该版本发布时newFactory方法尚未替代newInstance方法,不存在被调用的newFactory方法,判定为问题根因。
错误触发点为构建InteractiveBrowserCredential实例的逻辑:

this.interactiveBrowserCredential = new InteractiveBrowserCredentialBuilder()
            .clientId(clientId)
            .redirectUrl(myRedirectURL)
            .build();
现有配置与已尝试操作

当前项目build.gradle配置如下:

plugins {
    id 'com.android.application'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.organisation.appname"
        minSdk 26
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildFeatures {
        viewBinding true
    }

    packagingOptions {
        exclude 'project.properties'
        exclude 'META-INF/INDEX.LIST'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/AL2.0'
        exclude 'META-INF/LGPL2.1'
        exclude 'META-INF/io.netty.versions.properties'

        //pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'
    }
}

dependencies {
    //implementation 'javax.xml.stream:stax-api:1.0'
    //implementation 'stax:stax:1.2.0'
    implementation fileTree(include: ['*.aar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation('com.microsoft.graph:microsoft-graph:5.29.0') {
        //exclude group: "stax", module: "stax"
        //exclude group: "stax", module: "stax-api"
    }
    implementation 'com.google.guava:guava:30.1.1-android'
    implementation('com.azure:azure-identity:1.2.5') {
        //exclude group: "stax", module: "stax"
        //exclude group: "stax", module: "stax-api"
    }
    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.31"
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

业务逻辑代码片段:

public Emailing() {
        this.interactiveBrowserCredential = new InteractiveBrowserCredentialBuilder()
            .clientId(clientId)
            .redirectUrl(myRedirectURL)
            .build();

        this.tokenCredentialAuthProvider = new TokenCredentialAuthProvider(scopes, interactiveBrowserCredential);

        this.graphClient = GraphServiceClient
            .builder()
            .authenticationProvider(tokenCredentialAuthProvider)
            .buildClient();
}

public void emailForVisitorArrival(String name, String purpose, List<String> recipients) {
        Date timestamp = Calendar.getInstance().getTime();
        String timestampText = (String) DateFormat.format("dd MMM yyyy | hh:mm a", timestamp);

        Message message = new Message();
        message.subject = name + " has arrived.";
        ItemBody body = new ItemBody();
        body.contentType = BodyType.TEXT;
        body.content = myEmailContent;
        message.body = body;
        LinkedList<Recipient> toRecipientsList = new LinkedList<Recipient>();
        Recipient toRecipients = new Recipient();
        for (String recipient: recipients) {
            EmailAddress emailAddress = new EmailAddress();
            emailAddress.address = recipient;
            toRecipients.emailAddress = emailAddress;
            toRecipientsList.add(toRecipients);
            message.toRecipients = toRecipientsList;
        }

        graphClient.me()
                .sendMail(UserSendMailParameterSet
                        .newBuilder()
                        .withMessage(message)
                        .withSaveToSentItems(false)
                        .build())
                .buildRequest()
                .post();
}

已尝试以下操作但未解决问题:

  • 手动引入不同版本的stax依赖
  • 排除依赖树中的旧版stax依赖
修复步骤
  1. 在build.gradle中添加全局依赖强制规则,指定加载包含newFactory方法的stax-api版本,将以下配置放在android节点同级位置:
    configurations.all {
        resolutionStrategy.force 'javax.xml.stream:stax-api:1.0-2'
    }
    
    该版本已实现XMLInputFactory.newFactory静态方法,完全匹配Jackson XML组件的调用逻辑,避免使用存在缺陷的1.0.1版本。
  2. 修改packagingOptions规则,处理StAX服务配置文件冲突,取消原有注释并补充对应规则:
    packagingOptions {
        // 保留原有所有exclude规则
        pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'
        pickFirst 'META-INF/services/javax.xml.stream.XMLOutputFactory'
    }
    
  3. 检查libs目录下的本地aar包,如果有aar内置了旧版stax-api的class文件,手动解包移除内置的stax相关类后重新打包,避免本地aar类加载优先级高于远程依赖导致版本规则失效。
  4. 执行Gradle同步,清理构建缓存后重新编译运行即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:06:27