同一个包下的公开类编译时找不到。问题解决

本文解释了在使用Java命令行编译器时遇到的一个常见问题:当在一个包内的类引用另一个同包内类时,即使后者已被正确编译,前者在编译时仍可能无法找到该类。文章提供了详细的解决方案,并说明了为何在某些IDE中此问题不会出现。

学过java的人都知道,如果在同一个包下,一个类是可以直接引用同个包下的用public修饰的类。
但是有没有试过用doc命令行进去包目录结构下编译一个类时,这个类引用的同个包下的公开类编译时找不到(或许会报ClassNotFoundException),前提是被调用的公开类已经先被编译并通过了。

这里提供一个解决方法:
原因:其实这里出现的问题跟源文件没有任何关系,关键错在,你进去包目录下编译文件了,编译有包的源文件,应该在包的上一个目录去编译源文件,而且要带包结构。

举个例子:源文件目录结构是 src/carSystem/Car.java和src/carSystem/Rent.java,这两个文件的包是carSystem,而Rent.java有被Car.java引用的public类,所以,这时要先编译 javac carSystem/Rent.java,然后再 javac carSystem/Car.java

这里如果用eclipse或者myEclipse那肯定不会出现这个问题

最后在补充一下具体原因:你进入包目录下去javac Car.java的时候,因为这个java文件和Rent.java都是package carSystem的,所以他会在当前目录下去找carSystem目录下面的Rent这个类,然而,你的Rent.class是被编译到了当前CarSystem目录了,并不是当前目录的carSystem下。

也可以看看这个:

http://www.iteye.com/problems/34918

<think> 我们正在讨论的是在Android系统中使用`EthernetConfigStore`时遇到编译错误的问题。根据引用[1]和[3],`EthernetConfigStore`位于`frameworks/opt/net/ethernet/java/com/android/server/ethernet`路径下。因此,编译时不到的原因可能有以下几点: ### 1. **依赖缺失** - `EthernetConfigStore`是Android Framework内部的,位于`com.android.server.ethernet`包中。普通应用无法直接引用,因为它不是公开API(不在Android SDK中)。 - **解决方法**:只有系统应用(在系统分区中,具有系统签名)或系统服务才能访问。需要确保你的代码在系统环境中编译(如AOSP编译环境),并在模块的`Android.mk`或`Android.bp`中添加对应的依赖。 示例`Android.mk`片段: ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ... LOCAL_JAVA_LIBRARIES := services ethernet-service ... include $(BUILD_PACKAGE) ``` ### 2. **访问权限** - `EthernetConfigStore`的构造方法和关键方法可能不是`public`的,或者被`@hide`标记(隐藏API)。在非系统编译环境中,即使路径正确,也会因访问限制导致编译失败。 - **解决方法**:使用反射(不推荐,系统应用通常不必要)或确保代码在系统服务上下文中运行。 ### 3. **路径错误** - 代码中导入的包路径必须与源码路径完全一致。正确的导入语句应为: ```java import com.android.server.ethernet.EthernetConfigStore; ``` - **检查点**:确认你的代码中导入语句是否正确,且AOSP源码树中确实存在该(根据引用[1],Android O和P版本均有)。 ### 4. **版本兼容性** - 引用[2]提到,Android 13中以太网相关代码迁移到`packages/modules/Connectivity/`。若你在Android 12及以上版本开发,`EthernetConfigStore`可能已移动或重构。 - **解决方法**: - Android 12以下:使用`frameworks/opt/net/ethernet/`下的。 - Android 12+:在`packages/modules/Connectivity/service/`中查替代(如`EthernetTracker`)。 ### 5. **编译环境配置** - 在AOSP中编译系统应用时,需配置模块依赖。例如,在`Android.bp`中添加: ```json java_libraries { name: "ethernet-service", ... } ``` 并在你的模块中依赖它: ```json android_app { name: "MySystemApp", ... libs: ["ethernet-service"], } ``` ### 推荐解决方案 1. **确认路径**:在AOSP源码中全局搜索`EthernetConfigStore.java`,确认其存在位置。 2. **检查导入语句**:确保代码中的`import`与源码路径匹配。 3. **添加依赖**:在模块的编译配置文件中添加对`ethernet-service`库的依赖。 4. **处理版本差异**: - 若为Android 12+,参考引用[2]使用`EthernetManager`(公开API)替代部分功能: ```java EthernetManager manager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE); manager.setConfiguration(new IpConfiguration()); // 静态IP配置 ``` 注意:`setConfiguration`需要系统权限。 ### 示例:系统服务中使用EthernetConfigStore(Android 11) ```java // 正确导入 import com.android.server.ethernet.EthernetConfigStore; public class MyService { public void writeIpConfig() { // 需要系统上下文 EthernetConfigStore configStore = new EthernetConfigStore(context); IpConfiguration config = ...; // 创建配置 configStore.write(config); // 写入配置 } } ``` ### 相关问题 1. 如何在非系统应用中动态设置以太网IP? 2. Android 13中以太网API有哪些变更? 3. 如何为系统应用添加AOSP内部的编译依赖? 4. 调试系统服务时如何查看`EthernetConfigStore`写入的配置文件? </think> ### 在 Android 中添加 `EthernetConfigStore` 后编译报错的常见原因 #### 1. **路径不匹配** `EthernetConfigStore` 在不同 Android 版本中的位置发生变化(基于引用[1][2]): - **Android 8-11**:位于 `frameworks/opt/net/ethernet/java/com/android/server/ethernet/` - **Android 12+**:迁移到 `packages/modules/Connectivity/service/` 若在代码中使用旧路径(如 `com.android.server.ethernet.EthernetConfigStore`),但当前 SDK 版本已迁移路径,编译器将不到[^1][^2]。 #### 2. **依赖库缺失** `EthernetConfigStore` 属于系统内部,需在模块配置中添加依赖: ```gradle // Android.bp 或 build.gradle dependencies { implementation files("${ANDROID_ROOT}/frameworks/opt/net/ethernet/java/") // Android 11- // 或 implementation project(":packages_modules_Connectivity") // Android 12+ } ``` 未声明依赖会导致解析失败。 #### 3. **访问权限限制** 此被标记为 `@hide`(隐藏 API),普通应用无法直接访问: ```java // EthernetConfigStore.java 示例 @VisibleForTesting public class EthernetConfigStore { // @hide 标记 ... } ``` 需通过以下方式绕过限制: - **系统应用**:添加 `sharedUserId="android.uid.system"` - **反射调用**: ```java Class<?> ethernetClass = Class.forName("com.android.server.ethernet.EthernetConfigStore"); ``` #### 4. **版本兼容性问题** Android 13 中 `EthernetManager` 整体迁移(引用[2]),若在旧版本代码中使用新 SDK 编译或反之,会出现签名不匹配[^2]。 #### 5. **编译环境配置错误** 使用完整 AOSP 编译时需包含对应模块: ```shell # 确保包含 ethernet 模块 make EthernetService # Android 8-11 make com.android.ethernet # Android 12+ ``` 局部编译(如 Android Studio)可能缺少系统级依赖。 --- ### 解决方案步骤 1. **确认 Android 版本路径** 检查源码位置: ```bash # Android 11- find . -name EthernetConfigStore.java -path "*ethernet*" # Android 12+ find . -name EthernetConfigStore.java -path "*Connectivity*" ``` 2. **添加显式依赖** 在模块级 `build.gradle` 中: ```gradle android { sourceSets { main { java.srcDirs += [ "${ANDROID_ROOT}/frameworks/opt/net/ethernet/java/", "${ANDROID_ROOT}/packages/modules/Connectivity/service/" ] } } } ``` 3. **处理隐藏 API** 对于系统应用,在 `AndroidManifest.xml` 添加: ```xml <manifest xmlns:android="..." android:sharedUserId="android.uid.system"> ``` 4. **版本适配** 使用条件编译: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12+ 新路径 import com.android.net.module.util.EthernetConfigStore; } else { // Android 11- 旧路径 import com.android.server.ethernet.EthernetConfigStore; } ``` --- ### 验证方法 1. 检查编译日志是否包含路径扫描记录: ``` Scanning: frameworks/opt/net/ethernet/java/... ``` 2. 使用反编译工具查看 APK 是否包含目标: ```bash dexdump -d app.apk | grep EthernetConfigStore ``` ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值