2013-02-27 5 views
7

Ich versuche, eine Eigenschaftendatei aus Klassenpfad mit Hilfe von Scala zu lesen. Aber es sieht so aus, als würde es nicht funktionieren, es ist anders als Java. Das folgende 2 Code-Snippet, eines ist Java (funktioniert), ein anderes ist Scala (funktioniert nicht). Ich verstehe nicht, was der Unterschied ist.Read Eigenschaftendatei unter Klassenpfad mit Hilfe von Scala

// working 
BufferedReader reader = new BufferedReader(new InputStreamReader(
Test.class.getResourceAsStream("conf/fp.properties"))); 

// not working 
val reader = new BufferedReader(new InputStreamReader(
getClass.getResourceAsStream("conf/fp.properties"))); 

Exception in thread "main" java.lang.NullPointerException 
at java.io.Reader.<init>(Reader.java:78) 
at java.io.InputStreamReader.<init>(InputStreamReader.java:72) 
at com.ebay.searchscience.searchmetrics.fp.conf.FPConf$.main(FPConf.scala:31) 
at com.ebay.searchscience.searchmetrics.fp.conf.FPConf.main(FPConf.scala) 
+0

Warum verwenden Sie nicht [Config] (https://github.com/typesafehub/config)? –

+3

Die Lösung, ich sollte absoluten Pfad hier "/conf/fp.properties" verwenden, aber immer noch nicht klar, warum der relative Pfad in Java, aber nicht in Scala – zjffdu

Antwort

6

Ich vermute, dass Ihr BufferedReader ein java.io.BufferedReader

In diesem Fall ist können Sie einfach folgendes tun:

import scala.io.Source.fromUrl 
val reader = fromURL(getClass.getResource("conf/fp.properties")).bufferedReader() 

Dies lässt jedoch die Frage offen, was Sie planen mit der reader danach zu tun. scala.io.Source hat bereits einige nützliche Methoden, die ich eine Properties-Datei viel Code überflüssig .. see ScalaDoc

+0

Was ist, wenn Eigenschaftendatei in JAR-Datei (z. B. in Ressourcen dir) –

+0

[Von] (http://stackoverflow.com/questions/5285898/how-to-get-a-resource-within-scalatest-w-sbt): 'val source = Source.fromURL (getClass.getResource ("/conf/fp.properties "))' – suls

+0

das ist viel besser Ansatz –

2

Zum Lesen würde empfehlen, machen könnte java.util.ResourceBundle.getBundle("conf/fp") zu verwenden, es macht das Leben ein wenig leichter.

0

Die NullPointerException, die Sie sehen, wird durch einen Fehler im zugrunde liegenden Java-Code verursacht. Es könnte durch einen falsch eingegebenen Dateinamen verursacht werden.

Manchmal erhalten Sie diesen Fehler auch, wenn Sie versuchen, die Ressource mit dem falschen Classloader zu laden.

  1. Überprüfen Sie die Ressourcen-URL sorgfältig auf Ihren Klassenpfad.
  2. Versuchen Source.fromInputStream(getClass.getResourceAsStream(...))
  3. Versuchen Source.fromInputStream(getClass.getClassLoader.getResourceAsStream())
  4. Vielleicht versuchen Sie können Sie anderen Classloader verwenden?

Die gleiche Geschichte geht für Source.fromUrl(...)

Wenn Sie versuchen, Konfigurationsdateien zu laden und Sie ihr Format steuern, sollten Sie Config Dienstprogramm einen Blick auf die Typesafe haben.

0

Die Null-Zeiger-Ausnahme, die Sie erhalten, stammt von getResourceAsStream und gibt null zurück. Der folgende junit.scala-Ausschnitt zeigt, wie es einen Unterschied zwischen Klasse und Klassenlader gibt. siehe What is the difference between Class.getResource() and ClassLoader.getResource()?. Hier nehme ich an fileName ist der Name einer Datei im Klassenpfad, aber keine Datei neben der Klasse, die den Test ausführt.

assertTrue(getClass.getClassLoader().getResourceAsStream(fileName) != null) 
assertTrue(getClass.getClassLoader().getResourceAsStream("/" + fileName) == null) 
assertTrue(getClass.getResourceAsStream(fileName) == null) 
assertTrue(getClass.getResourceAsStream("/" + fileName) != null) 
5

Dieser Code arbeitete schließlich für mich:

import java.util.Properties 
import scala.io.Source 

// ... somewhere inside module. 

var properties : Properties = null 

val url = getClass.getResource("/my.properties") 
if (url != null) { 
    val source = Source.fromURL(url) 

    properties = new Properties() 
    properties.load(source.bufferedReader()) 
} 

Und jetzt haben Sie nur alte java.util.Properties zu handhaben, was eigentlich mein Legacy-Code benötigt zu erhalten.

0

Meine bevorzugte Lösung ist mit . Ich habe eine application.conf Datei in Haupt \ resources-Ordner mit Inhalt wie gesagt:

services { mongo-db { retrieve = """http://xxxxxxxxxxxx""", base = """http://xxxxxx""" } }

und die es in einer Klasse zu verwenden, laden Sie zuerst die Config Fabrik von typsicher und dann benutzen Sie es einfach.

val conf = com.typesafe.config.ConfigFactory.load() conf.getString("services.mongo-db.base"))

Hoffe, es hilft!

Ps. Ich wette, dass jede Datei auf Ressourcen mit .conf als Erweiterung gelesen wird.

Verwandte Themen