必需的链接设置

链接构建步骤(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_security 中,而 javax.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 util 类作为静态库包含在 J2ObjC 发行版中:

媒体库链接标记说明
libguava.a -l 番石榴 Guava:适用于 Java 的 Google 核心库
libjavax_inject.a -l javax_inject JSR-330 依赖项注入注解库。
libjson.a -l JSON JSON 数据交换库。这是 Android 版本的 JSON,与其他实现略有不同。
libjsr305.a -l jsr305 用于软件缺陷检测库的 JSR-305 注释。
libjunit.a -l junit -ObjC JUnit 测试框架。
libmockito.a -l mockito -ObjC 适用于 Java 单元测试的 Mockito 模拟框架。
libprotobuf_runtime.a -l protobuf_runtime 针对 J2ObjC 应用进行了优化的 Google 协议缓冲区运行时。使用 J2ObjC protobuf 的应用应使用 j2objc_protoc 编译其 proto 文件。
libandroid_util.a -l android_util “android_util”库包含一小部分 Android API 实用程序类。它的目的不是为 Android 环境提供模拟,而只是为了提供一种共享实用类(如“android.util.Log”)的方式。

-ObjC 标记经常在链接 iOS 应用时使用,但仅在需要从静态库动态加载 Objective C 类和类别时才是必需的。此标志会导致所有链接的静态库中的所有类都包含在应用中,无论它们是否实际使用。因此,当类在运行时未能加载时(一个症状就是抛出 JavaLangClassNotFoundException),建议使用 J2ObjC 的应用仅在类运行时通过 -ObjC 标志链接。

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
  };