必要的連結設定

連結建構步驟 (Xcode 的「Link Binary With Libraries」) 需要 J2ObjC 專用的標記,這會因應用程式使用已翻譯 Java 類別的方式而異。核心標記是由 j2objcc 指令列指令碼設定,但使用 Xcode 進行建構時需要指定。

SDK 程式庫

J2ObjC 的 JRE 實作需要這個程式庫。如未加入這個程式庫,會導致名稱開頭為 _iconv 的未定義符號錯誤。

媒體庫連結標記說明
iconv -l 圖示 jre_core 用於字元編碼及解碼。

J2ObjC 的 JRE 實作會使用這些程式庫,而且這類程式庫可能需要連結至應用程式。

媒體庫連結標記說明
zip -l z 由 java.util.zip 使用。如要連結 jre_zip,必須加入這個欄位。
安全性 -架構安全性 如果連結 jre_security,則為必要欄位。

圖書館搜尋路徑

J2ObjC 的發布包含數個靜態程式庫;如要使用這些程式庫,您的專案必須告知連接器在何處找到這些程式庫。

一般而言,程式庫搜尋路徑必須包含 _$(j2objcdistribution)/lib,其中 _$(j2objcdistribution) 變數是 J2ObjC 本機副本的路徑。舉例來說,如果您將J2ObjC 版本封存檔解壓縮到「/usr/local/」,路徑會是「/usr/local/j2objc」。

重要事項:請勿在專案中實際使用 _$(j2objcdistribution)。請一律指定安裝 J2ObjC 的實際路徑。

如果您是從原始碼副本建構 J2ObjC,則 _$(j2objcdistribution) 是副本的「j2objc/dist/」目錄。您必須使用 make dist 建構 J2ObjC,這個目錄才會存在。

Xcode:資料庫搜尋路徑

新增 _$(j2objcdistribution)/lib,更新應用程式目標的程式庫搜尋路徑 (再次使用實際路徑)。

JRE 程式庫

這些程式庫會實作 J2ObjC 的 JRE 模擬所定義的類別。

注意:libjre_core.a 程式庫包含大多數其他子程式庫的類別。如要縮減應用程式大小,建議您開始將應用程式與 -l jre_core 連結,然後新增可解析任何缺少符號的子集程式庫。例如,最常用的 java.io 類別位於 libjre_core.a,因此只有在名稱開頭為 JavaIo 的未解析符號錯誤時,才要加入 libjre_io.a 程式庫。

媒體庫連結標記說明
libjre_core.a -l jre_core 所有產生的來源檔案都參照 J2ObjC 的 JRE 模擬所需的 類別下限。如果您翻譯的 Java 來源參照了網路、XML、SQL 等項目的 JRE 支援,則您也必須連結其他程式庫 (如下所述)。
libjre_beans.a -l jre_beans java.beans 套件中的 所有類別。並非所有 Java Beans 類別,因為許多只有 Swing 和 AWT 應用程式才會使用。
libjre_channels.a -l jre_channels java.nio.channelsjava.nio.channels.spi 套件中的 多種類別
libjre_concurrent.a -l jre_concurrent java.util.concurrentjava.util.concurrent.atomicjava.util.concurrent.locks 套件中的 多個類別
libjre_icu.a -l jre_icu android.icu 多種類別支援時區 (主要會啟用 java.time)。
libjre_io.a -l jre_io java.io 套件中的 多個 (較少使用) 類別
libjre_net.a -l jre_net java.net 套件中的 多個類別。不過,java.net.URLClassLoader 類別位於 jre_securityjavax.netjavax.net.ssl 類別則位於 jre_ssl
libjre_security.a -l jre_security java.security 套件中的 大多數類別 (幾個類別位於 jre_core),以及 java.security.*javax.crypto.*javax.security.* 套件中的類別。如果連結帳戶,您還必須連結 iOS 安全性架構。 (請參閱 SDK 程式庫)
libjre_sql.a -l jre_sql java.sql 套件中的 所有類別
libjre_ssl.a -l jre_ssl javax.netjavax.net.ssl 套件中的 所有類別
libjre_time.a -l jre_time java.time 套件中的 所有類別
libjre_util.a -l jre_util java.util 套件中的 多種類別,以及 java.util.logging 套件。不過,大部分的 java.util 類別都在 jre_core 中,因此只有在發生未解決的 JavaUtil* 符號錯誤 (JavaUtilConcurrent* 符號位於 jre_concurrent 程式庫中) 時,才要加入這個程式庫。
libjre_xml.a -l jre_xml XML 相關套件中的 所有類別,包括 javax.xml.*org.w3c.dom.*org.xml.sax.*
libjre_zip.a -l jre_zip java.util.zipjava.util.jar 套件中的 所有類別。如果建立連結,您也需要連結 SDK ZIP 程式庫。(請參閱「SDK 程式庫」)

libjre_emul.a (-l jre_emul)

jre_emul 程式庫包含 J2ObjC 的 JRE 模擬中的所有類別。如果應用程式已經與 jre_emul 連結,則不應加入其他的 jre_* 程式庫,或者連結器會回報重複的符號錯誤。這是因為 jre_emul 包含這些程式庫中定義的所有類別。

其他 J2ObjC 程式庫

這些 Java 程式庫和 Android 公用程式類別會以靜態程式庫的形式包含在 J2ObjC 發行中:

媒體庫連結標記說明
libguava.a -l Guava Guava:Java 適用的 Google Core Library
libjavax_inject.a -l javax_inject JSR-330 依附元件插入註解資料庫。
libjson.a -l JSON JSON 資料交換程式庫。這是 JSON 的 Android 版本,與其他實作方式略有不同。
libjsr305.a -l jsr305 軟體瑕疵偵測程式庫的 JSR-305 註解。
libjunit.a -l junit -ObjC JUnit 測試架構。
libmockito.a -l mockito -ObjC Mockito 模擬架構:適用於 Java 中的單元測試。
libprotobuf_runtime.a -l protobuf_runtime 已針對 J2ObjC 應用程式進行最佳化的 Google 通訊協定緩衝區執行階段。使用 J2ObjC protobufs 的應用程式應使用 j2objc_protoc 編譯 proto 檔案。
libandroid_util.a -l android_util 「android_util」程式庫包含一小部分的 Android API 公用程式類別。這並非為 Android 環境提供模擬,而只是為了分享「android.util.Log」等實用類別的方法。

連結 iOS 應用程式時經常會使用 -ObjC 旗標,但只有當 Objective C 類別和類別需要從靜態程式庫動態載入時,才需要使用這個標記。這個標記會使所有已連結靜態程式庫中的所有類別加入應用程式,無論類別是否實際使用。因此,我們建議使用 J2ObjC 的應用程式在執行階段無法載入類別時,只將類別與 -ObjC 標記連結 (一個符號就是擲回 JavaLangClassNotFoundException 時)。

JUnit 和 Mockito 測試架構十分仰賴反射,因此使用這些架構的測試應用程式應與 -ObjC 連結。

如要在整個靜態資料庫中進行連結,改為動態載入幾個類別,請改為靜態參照這些類別。在 Java 中,您可以在靜態初始化器區塊中完成這項作業;以下是 J2ObjC 的 IosSecurityProvider 類別的範例:

  // Reference all dynamically loaded classes, so they are linked into apps.
  @SuppressWarnings("unused")
  private static final Class<?>[] unused = {
    IosCertificateFactory.class,
    IosMD5MessageDigest.class,
    IosRSAKeyFactory.class,
    IosRSAKeyPairGenerator.class,
    IosRSASignature.class,
    IosSecureRandomImpl.class,
    IosSHAMessageDigest.class
  };