我創建了一個簡單的 Java9 服務示例,其中包含一個服務接口、兩個服務實現以及一個使用 ServiceLoader 的驅動程序。我能夠使用 module-path 成功執行該示例,但是當我嘗試使用 java -cp (classpath) 執行相同的示例時,我沒有得到任何輸出,甚至沒有任何錯誤。目錄結構out├── driver│ ├── com│ │ └── company│ │ └── driver│ │ └── driver.class│ └── module-info.class├── firstServiceImpl│ ├── com│ │ └── company│ │ └── first│ │ └── serviceImpl│ │ └── FunImpl1.class│ └── module-info.class├── secondServiceImpl│ ├── com│ │ └── company│ │ └── second│ │ └── serviceImpl│ │ └── FunImpl2.class│ └── module-info.class└── serviceInterface ├── com │ └── company │ └── service │ └── Fun.class └── module-info.class編譯命令javac -d out --module-source-path src src/driver/driver.java src/firstServiceImpl/FunImpl1.java src/secondServiceImpl/FunImpl2.java src/serviceInterface/Fun.java上面的命令使用module-source-path編譯代碼。運行命令java -cp out/driver:out/serviceInterface/:out/firstServiceImpl/ com.sunil.driver.driver上面的命令使用classpath運行代碼。使用module-source-path編譯并使用classpath運行代碼后。我沒有收到任何錯誤或輸出。請幫助我理解為什么使用classpath運行時沒有輸出。
1 回答

滄海一幻覺
TA貢獻1824條經驗 獲得超5個贊
服務提供者的定位方式取決于服務提供者是否位于類路徑或模塊路徑上。這在以下文檔中進行了描述ServiceLoader
:
將服務提供者部署為模塊
在模塊中開發的服務提供者必須在模塊聲明中的provided指令中指定。Provides 指令指定了服務和服務提供者;當另一個帶有該服務的use指令的模塊獲取該服務的服務加載器時,這有助于定位提供者。強烈建議模塊不要導出包含服務提供者的包。不支持模塊在提供指令中指定另一個模塊中的服務提供者。
[...]
在類路徑上部署服務提供者
打包為類路徑的 JAR 文件的服務提供者通過將提供者配置文件放置在資源目錄中來標識
META-INF/services
。提供程序配置文件的名稱是服務的完全限定二進制名稱。提供者配置文件包含服務提供者的完全限定二進制名稱列表,每行一個。[...]
基本上,如果您希望能夠加載服務提供程序,無論它是否放置在類路徑或模塊路徑上,您都需要在文件中指定指令并provides
在.?您還必須確保使用正確的方法來加載服務提供者:module-info.java
META-INF/services
ServiceLoader#load(Class,ClassLoader)
在命名模塊(即模塊路徑)和未命名模塊(即類路徑)中定位提供程序。
ServiceLoader#load(ModuleLayer,Class)
僅在命名模塊(即模塊路徑)中定位提供程序。
添加回答
舉報
0/150
提交
取消