resources内のファイルを読み込み
以下のコードは、KtorでFirebaseの初期化をするためにfirebase-adminsdk.json
をFileInputStream
で読み込んでいます。
// Application.kt fun Application.initializeFirebaseApp() { val serviceAccount = FileInputStream("resources/firebase-adminsdk.json") val databaseUrl = "DATABASE_URL" val storageUrl = "STORAGE_URL" val options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount)) .setDatabaseUrl(databaseUrl) .setStorageBucket(storageUrl) .build() if (FirebaseApp.getApps().isEmpty()) FirebaseApp.initializeApp(options) }
このコードを実行するApplication.kt
とfirebase-adminsdk.json
は以下のように配置しています。
IDEでビルドしてデバッグしている分には問題なく動作しますが、Jar出力して実行するとjava.io.FileNotFoundException
がスローされてしまいます。
Caused by: java.io.FileNotFoundException: resources/firebase-adminsdk.json (No such file or directory)
解決方法
FileInputStream
を取得するコードを修正します。
// Application.kt fun Application.initializeFirebaseApp() { val serviceAccount = javaClass.classLoader.getResourceAsStream("firebase-adminsdk.json") // ... }
また、build.gradle.kts
でsourceSets
の設定が必要です。
kotlin.sourceSets["main"].kotlin.srcDirs("src/main") sourceSets["main"].resources.srcDirs("resources")
getResourceAsStream
とは?
実装に必要なリソースファイル(テキスト、イメージ)を読み込むことができます。 ドキュメントでは「位置に依存しない方法でのリソースへのアクセス」の方法として説明させています。
今回のようにフォルダ構造に合わせてパスを指定して問題があるときは、getResourceAsStream
を使うのが良さそうです。
そもそも絶対パスや相対パスで指定していると、リファクタしにくいので適切にsourceSets
及びresources
を使用した方が良さそうです。