Android API 30下org.apache.xerces相关类找不到问题求助
解决Android API 30下com.akamai:edgeauth:0.2.0的DatatypeFactoryImpl找不到问题
问题原因
Android从API 26开始移除了大部分内置的javax.xml相关实现,API 30进一步收紧了对非系统类加载的限制。而com.akamai:edgeauth:0.2.0是一个多年未维护的过时库,依赖的Xerces组件在新版Android环境下无法被正确加载,导致org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl找不到的错误。
解决方案
方案1:调整依赖并强制指定DatatypeFactory实现
修改Gradle依赖配置
替换原有依赖配置,排除旧库中冲突的XML相关依赖,添加兼容的JAXB运行时库:implementation ('com.akamai:edgeauth:0.2.0') { exclude group: 'xerces', module: 'xercesImpl' exclude group: 'javax.xml.bind', module: 'jaxb-api' exclude group: 'javax.xml.datatype', module: 'jsr173-api' } // 添加兼容的JAXB运行时,提供必要的XML处理实现 implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.6'在应用启动时指定DatatypeFactory
在自定义Application类的onCreate方法中设置系统属性,强制使用Android内置的Xerces实现类:@Override public void onCreate() { super.onCreate(); // 强制指定适配Android的DatatypeFactory实现 System.setProperty("javax.xml.datatype.DatatypeFactory", "com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl"); }注意:确保已在
AndroidManifest.xml中注册该自定义Application类。
方案2:替换为自定义实现(推荐)
由于com.akamai:edgeauth:0.2.0已多年未维护(最后更新于2017年),长期来看兼容性风险高。可以参考原库的核心逻辑,自行实现EdgeAuth Token生成:
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Map; import java.util.TreeMap; public class EdgeAuthTokenGenerator { public static String generateToken(String secretKey, String resourceUrl, long expirationTimestamp) { // 按字典序排序参数,确保签名一致性 TreeMap<String, String> tokenParams = new TreeMap<>(); tokenParams.put("exp", String.valueOf(expirationTimestamp)); tokenParams.put("url", resourceUrl); // 构建待签名的字符串 StringBuilder signContent = new StringBuilder(); for (Map.Entry<String, String> entry : tokenParams.entrySet()) { signContent.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } String rawSignData = signContent.substring(0, signContent.length() - 1); try { // 生成HMAC-SHA256签名 Mac hmacSha256 = Mac.getInstance("HMAC-SHA256"); SecretKeySpec secretSpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HMAC-SHA256"); hmacSha256.init(secretSpec); byte[] signatureBytes = hmacSha256.doFinal(rawSignData.getBytes(StandardCharsets.UTF_8)); String urlSafeSignature = Base64.getUrlEncoder().encodeToString(signatureBytes); // 拼接最终Token return String.format("exp=%d&url=%s&sig=%s", expirationTimestamp, resourceUrl, urlSafeSignature); } catch (Exception e) { throw new RuntimeException("Failed to generate EdgeAuth token", e); } } }
该实现仅依赖JDK标准类,完全适配新版Android环境,且避免了第三方依赖的兼容性问题。
内容的提问来源于stack exchange,提问作者Tarun Deep Attri
相关产品推荐
相关产品推荐

