記錄下 Java 8 policy tool 升級致使編譯安卓時 Jack server 出錯,主要是其中的java啓動參數 -Djavax.net.debug=ssl
調試方法,之後遇到相似問題好快速的解決。
另外僅Android6~Android8.1使用jack編譯,8.1以後已廢棄該工具,詳情可看下 https://source.android.google...java
你們的電腦升級後,編譯安卓8.1的源碼出錯,communication error with Jack server, SSL_ERROR_SYSCALLandroid
communication error with Jack server (35), try 'jack-diagnose' or see Jack server log curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:8077
而後就解決吧,結果按照網上以前出現問題的方案解決都不行,這個也浪費了你們好幾天的時間。
我以前是按照笨方法對比替換解決的,以後網上查資料才找到調試方法(原網頁已不記得是哪一個了,見諒),若是按該方法調試,應該能夠很快就能夠解決問題。git
jack server的日誌存放在 ~/.jack-server/logs
, 然而日誌裏沒有錯誤日誌。shell
經過分析 prebuilts/sdk/tools/jack-admin
, 發現能夠用 curl -v https://127.0.0.1:8076
命令去測試,這樣方便快速調試。
然而呢就是https鏈接,第二階段握不上手,app
# 鏈接jack端口握手失敗 $ curl -v https://127.0.0.1:8076 * Trying 127.0.0.1:8076... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8076 (#0) ... * TLSv1.3 (OUT), TLS handshake, Client hello (1): * OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 127.0.0.1:8076 * Closing connection 0 curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 127.0.0.1:8076
正常狀況下,第一階段 Client hello
後會有第二階段 Server hello
, 但就是沒出現這樣的語句curl
TLS handshake, Server hello (2):
使用不一樣的tls版本也一樣的結果jvm
# 使用不一樣tls版本鏈接 for args in "tlsv1.3" "tlsv1.2" "tlsv1" ;do curl -v --$args https://127.0.0.1:8076;echo ----; done
反正折騰了一大圈,到解決該問題後,其實正確的調試方式應該是,
分析jack-admin裏start-server和日誌,
本身手動啓動,其中關鍵的是添加 -Djavax.net.debug=ssl
調試參數,固然ssl也可改成all,這樣日誌會全一些。工具
# 手動啓動jack-server並加調試參數 $ prebuilts/sdk/tools/jack-admin kill-server # 注意須要把以前已經起來的jack server殺了 # 添加 -Djavax.net.debug=ssl $ cd ~/.jack-server $ java -XX:MaxJavaStackTraceDepth=-1 -Djavax.net.debug=ssl -Djava.io.tmpdir=/tmp -Dfile.encoding=UTF-8 -cp ~/.jack-server/launcher.jar com.android.jack.launcher.ServerLauncher
這個時候再用命令行 curl...去鏈接在終端就會出現錯誤日誌 protocol is disabled or cipher suites are inappropriate
測試
"throwable" : { javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171) at sun.security.ssl.ServerHandshakeContext.<init>(ServerHandshakeContext.java:62) at sun.security.ssl.TransportContext.kickstart(TransportContext.java:220)
順着這個錯誤日誌去網上搜索其實就能夠很快解決問題了。ui
修復方法倒想着有幾個,可選擇本身喜歡的方案,有別的方案也歡迎評論。
將禁用的TLSv1啓用,最好也啓用SSLv3, 反正源碼裏寫的是SSLv3。
(關於TLS, SSL區別這些可網上查查,這裏不列出)
# 使用TLSv1 /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security --- java.security 2021-04-30 13:44:46.922768831 +0800 +++ java.security.NG 2021-04-30 13:31:38.754028864 +0800 @@ -716,7 +716,7 @@ # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, RC4, DES, MD5withRSA, \ +jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
可經過設置JAVA_HOME等方式,使用自帶的JDK prebuilts/jdk/jdk8/ 。
事實上,安卓後續的版本都用的自帶的JDK。
jack源碼在 https://android.googlesource.... , 須要想辦法訪問。
最新分支應該爲 ub-jack , 17年就再也不維護了。
# 下載jack源碼 $ git clone https://android.googlesource.com/toolchain/jack -b ub-jack --depth 1
修改的源碼示例:
--- .../android/jack/server/JackHttpServer.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/server/jack-server/src/com/android/jack/server/JackHttpServer.java b/server/jack-server/src/com/android/jack/server/JackHttpServer.java index 4e5e75c3..7aa602ee 100644 --- a/server/jack-server/src/com/android/jack/server/JackHttpServer.java +++ b/server/jack-server/src/com/android/jack/server/JackHttpServer.java @@ -1391,6 +1391,7 @@ public class JackHttpServer implements HasVersion { FileInputStream keystoreServerIn = null; FileInputStream keystoreClientIn = null; SSLContext sslContext = null; + String[] httpsProtocols = {"TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"}; try { File keystoreServerFile = new File(serverDir, KEYSTORE_SERVER); @@ -1416,12 +1417,29 @@ public class JackHttpServer implements HasVersion { TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tm.init(keystoreClient); - sslContext = SSLContext.getInstance("SSLv3"); + logger.log(Level.INFO, "Java version " + System.getProperty("java.version")); + logger.log(Level.INFO, "Supported protocols " + Arrays.toString(SSLContext.getDefault().getSupportedSSLParameters().getProtocols())); + for (String protocol : httpsProtocols) { + try { + sslContext = SSLContext.getInstance(protocol); + } catch (NoSuchAlgorithmException e) { + continue; + } + logger.log(Level.INFO, "Found protocols " + protocol); + break; + } + + if (sslContext == null) { + throw new NoSuchAlgorithmException(); + } + sslContext.init(keyManagerFactory.getKeyManagers(), tm.getTrustManagers(), null); } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException | CannotCreateFileException | CannotChangePermissionException e) { throw new ServerException("Failed to setup ssl context", e); + } catch (Exception e) { + logger.log(Level.INFO, "Ssl error " + e); } finally { if (keystoreClientIn != null) { try { -- 2.31.1
以後把 prebuilts/sdk/tools/Android.mk 裏jack相關的去掉後,編譯jack-server源碼,
替換 prebuilts/sdk/tools/jack-server-4.11.ALPHA.jar
~/.jack-server/server-*.jar
隨後 jack-admin kill-server,再編譯安卓便可正常。