Android_Uiautomatorviewer Not Support/无法初始化主类问题分析与解决-无需更换 JDK

参考

  1. 大体排查思路参考
  2. -Djava.ext.dirs 参数究竟是什么东西
  3. JDK8 中使用 -Djava.ext.dirs 参数来在运行 Jar 包中导入其他 Jar
  4. 在运行 Jar 包中导入其他 Jar 的常用方法

自己的碰到的问题

折腾 Appium 的时候要看 APP 的页面元素嘛; 然后就是用 Uiautomatorviewer 来看,结果闪退无法打开, 我自己装的是 JDK11 绿色版,还挺喜欢这个版本,又不想换 JDK8,然后就开始折腾,主要遇到的问题有两个:

  1. -Djava.ext.dirs not support,意思是这个参数在 JDK11 不再支持了, 要求你使用 -classpath/–class-path 参数,然后如果你用了这个参数会出现下面的第二个问题
  2. 无法初始化主类问题

解决问题

虽然看不懂 .bat,但是还是硬着头皮看了,我给你们大体分析下

...
这是原版的代码,我加了几行打印语句调试,顺便提一句 rem 在 .bat 中应该是注释的意思, echo 就是打印,懂得都懂
前面的代码大体就干了两件事,找 Java,找各种各样的路径,为了最后一行代码执行真正的程序做准备的

rem lib\x86_64;lib
echo %javaextdirs%

rem D:\Dev\SDKTools-r24.4.1\tools
echo %prog_dir%

rem lib\uiautomatorviewer.jar
echo %jarpath%

call "%java_exe%" "-Djava.ext.dirs=%javaextdirs%" "-Dcom.android.uiautomator.bindir=%prog_dir%" -jar %jarpath% %*

所以上面的最后一行代码,其实是想执行这样一条 java 命令

java -Djava.ext.dirs=lib\x86_64;lib -Dcom.android.uiautomator.bindir=D:\Dev\SDKTools-r24.4.1\tools -jar lib\uiautomatorviewer.jar

// 我解释一下这条命令
// 先看第二个 -D,意思是给 JVM 设置启动参数
// -jar 说明它是想 Java 执行一个封装好的 Jar 文件
// 在看第一个 -D,意思也是给 JVM 设置启动参数,但是这个参数非同凡响,可以做到运行的 Jar 导入依赖的 Jar, 详细可以看参考链接 2,3

// 所以这整句命令的意思是:
// 运行 lib\uiautomatorviewer.jar ,并从 lib\x86_64;lib 目录中找到该 Jar 所依赖的 Jar

想法很美好,但是有一个问题, -Djava.ext.dirs 参数在 JDK8 以上应该是失效的,因此一个直接的结果就是 -Djava.ext.dirs not support, 网上有一个针对此项的改法,改成 --class-path=, 但是,这种改法是错误的,参见参考链接4,引用原话如下:

java -classpath some.jar -jar test.jar
这种方式是不行的,因为使用 classpath 指定的 jar 是由 AppClassloader 来加载,java 命令加了-jar 参数以后,AppClassloader 就只关注 test.jar 范围内的 class 了,classpath 参数失效。那该怎么引用其他的 jar 包呢?

简而言之,classpath 指定的是运行 jar 的寻找路径,而不是添加其所依赖 jar 的依赖,这句话我瞎蒙的,但是应该就是这样

那么到底怎么添加其所缺少的 swt.jar 呢?
我根据链接4选择了我认为的最简单一种方法: 修改 Jar 中 META-INF/MANIFEST.MF 文件
原文件如下:

Manifest-Version: 1.0
Main-Class: com.android.uiautomator.UiAutomatorViewer
Class-Path:  org-eclipse-jface-3.6.2.jar ddmlib.jar org-eclipse-core-c
 ommands-3.6.0.jar org-eclipse-equinox-common-3.6.0.jar osgi-4.0.0.jar
  common.jar kxml2-2.3.0.jar annotations.jar guava-17.0.jar

我们只需要在末尾添加 swt.jar 的相对路径即可, 其他 Jar 都在同级目录下真是帮大忙了,修改如下:

Manifest-Version: 1.0
Main-Class: com.android.uiautomator.UiAutomatorViewer
Class-Path:  org-eclipse-jface-3.6.2.jar ddmlib.jar org-eclipse-core-c
 ommands-3.6.0.jar org-eclipse-equinox-common-3.6.0.jar osgi-4.0.0.jar
  common.jar kxml2-2.3.0.jar annotations.jar guava-17.0.jar x86_64/swt.jar

然后由于我们手动显式添加了 swt.jar,并且其他 jar 都在同级目录,因此 java 命令中就可以直接运行,不需要加什么参数了,.bat 文件修改如下:

call "%java_exe%" "-Dcom.android.uiautomator.bindir=%prog_dir%" -jar %jarpath% %*

大功告成

写在最后

捣鼓了挺久,希望能帮助大家,或者给大家提供一点思路

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值