J'utilise le code suivant pour lire un fichier de propriétés:
Properties pro = new Properties();
InputStream is = Thread.currentThread().getContextClassLoader().
getResourceAsStream("resources.properties");
pro.load(is);
Et lorsque j'exécute le code, j'obtiens l'erreur suivante:
Exception in thread "main" Java.lang.NullPointerException
at Java.util.Properties$LineReader.readLine(Properties.Java:418)
at Java.util.Properties.load0(Properties.Java:337)
at Java.util.Properties.load(Properties.Java:325)
at com.ibm.rqm.integration.RQMUrlUtility.RQMRestClient.getResource(RQMRestClient.Java:66)
at com.ibm.rqm.integration.RQMUrlUtility.RQMRestClient.main(RQMRestClient.Java:50)
Pourquoi ai-je un NullPointerException
? Et où dois-je enregistrer le resources.properties
fichier?
Il ressemble à ClassLoader.getResourceAsStream(String name)
renvoie null
, ce qui fait que Properties.load
Lance NullPointerException
.
Voici un extrait de la documentation:
URL getResource(String name)
: Recherche la ressource avec le nom donné. Une ressource est une donnée (images, audio, texte, etc.) accessible par le code de classe d'une manière indépendante de l'emplacement du code.Le nom d'une ressource est un nom de chemin séparé par
'/'
Qui identifie la ressource.Renvoie: Un objet
URL
pour lire la ressource, ounull
si:
- la ressource est introuvable, ou
- l'invocateur n'a pas les privilèges adéquats pour obtenir la ressource.
getResource
La correction de bugs est plus facile si vous écrivez plus de lignes, comme:
Properties properties = new Properties();
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
InputStream propertiesStream = contextClassLoader.getResourceAsStream("resource.properties");
if (propertiesStream != null) {
properties.load(propertiesStream);
// TODO close the stream
} else {
// Properties file not found!
}
J'ai eu le même problème et j'étais assez confus car je l'ai utilisé précédemment dans une application Sturts. Mais le problème était que je ne comprenais pas le type de ClassLoader que Struts renvoie est différent de ce que Spring renvoie. Et la façon dont je l'ai compris était d'imprimer l'objet renvoyé à la console système comme ceci:
System.out.println(Thread.currentThread().getContextClassLoader());
[
WebappClassLoader
contexte:/MyProject
délégué: faux
référentiels:
/WEB-INF/classes /
----------> Chargeur de classe parent:
org.Apache.catalina.loader.StandardClassLoader@1004901
Il m'a donné le détail de l'objet, et en ce que j'ai trouvé que son type était de WebAppClassLoader qui commencera à rechercher des fichiers dans le dossier WEB-INF/classes/après la construction. Je suis donc allé dans ce dossier et j'ai cherché où se trouvait mon fichier, alors j'ai donné le chemin en conséquence.
Dans mon cas, il se trouvait dans /WEB-INF/classes/META-INF/spring/filename.extension
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/spring/filename.extension");
Cela a tout réglé.
J'ai eu le même problème et j'ai résolu en procédant comme suit
File file = new File("resources.properties");
System.out.println(file.getAbsolutePath());
puis placez le fichier "resources.properties" sous ce chemin.
Beaucoup semblent avoir ce problème et comme moi, ils abandonnent après un certain temps. Voici ce que je devais faire fonctionner. L'astuce ici pour utiliser le chemin relatif pour la recherche de fichiers est de vous assurer que votre dossier de classes contient des fichiers de ressources ainsi que des fichiers src. Voici ce que j'ai fini par faire.
1) Si vous utilisez Eclipse, assurez-vous que le paramètre .classpath approprié est présent et faites NETTOYAGE DU PROJET pour voir les fichiers de ressources générés sous/classes. Notez les entrées de chemin de classe ci-dessous pour les fichiers de ressources placés sous src/main/resource
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.Java" kind="src" output="target/test-classes" path="src/test/Java"/>
<classpathentry including="**/*.Java" kind="src" path="src/main/Java"/>
<classpathentry kind="var" path="M2_REPO/javax/mail/mail/1.4.4/mail-1.4.4.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
<classpathentry kind="con" path="org.Eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
2) Si vous utilisez également maven, assurez-vous de configurer votre pom.xml conformément à la https://maven.Apache.org/guides/introduction/introduction-to-the-pom.html et faire mvn clean install pour voir les fichiers sous target/classes
3) Une fois que vous avez les fichiers de ressources sous/classes, la prochaine chose à faire dans Java est la suivante. N'oubliez pas d'avoir la barre oblique.
try {
properties.load(getClass().getResourceAsStream("/mail-config.properties"));
} catch (IOException e) {
e.printStackTrace();
}
J'aurais pu ajouter quelques images mais je n'avais pas de points. :)
En fait ça dépend; Selon javadoc ... Le contexte ClassLoader est fourni par le créateur du thread pour être utilisé par le code exécuté dans ce thread lors du chargement des classes et des ressources. S'il n'est pas défini, la valeur par défaut est le contexte ClassLoader du thread parent. Le contexte ClassLoader du thread primordial est généralement défini sur le chargeur de classe utilisé pour charger l'application ...
Donc, si Thread.currentThread().getContextClassLoader()
est dans la fonction main () et que vous n'avez pas créé de thread, alors il devrait avoir le même package que celui de la classe contenant la méthode main. Sinon, il devrait être présent dans la classe qui a créé le thread ....
Peut-être, j'ai arraché tous mes cheveux et en partant, j'ai trouvé cette solution:
Properties dbParamProperties = new Properties();
InputStream input = null;
try {
String pathOfAbsolute = this.getClass().getProtectionDomain().getCodeSource().getLocation().toString();
String propertiesFilePath = pathOfAbsolute+"/properties/conf.properties";
propertiesFilePath = propertiesFilePath.replace("file:/", "").replace("/", "\\");
System.out.println(pathOfAbsolute);
System.out.println(propertiesFilePath);
Paths.get(new URI(pathOfAbsolute));
input = ClassLoader.getSystemResourceAsStream(propertiesFilePath);
input = new FileInputStream(propertiesFilePath);
dbParamProperties.load( input );
dbUID = dbParamProperties.getProperty("userName");
dbURL = dbParamProperties.getProperty("hosturl");
dbPWD = dbParamProperties.getProperty("password");
dbPort = dbParamProperties.getProperty("port");
dbSID = dbParamProperties.getProperty("servicenameorsid");
} catch (IOException e) {
e.printStackTrace();
}
catch(Exception ex){
ex.printStackTrace();
}
J'ai eu ce problème avec un programme tiers et il s'est avéré que je devais inclure .
dans le chemin de classe pour que le programme puisse lire un fichier de propriétés local dans le répertoire de travail courant.
J'ai eu le même problème et cela m'a aidé:
InputStream is;
try {
is = this.getClass().getClassLoader().getResourceAsStream("config.properties");
prop.load(is);
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String pass = prop.getProperty("password");
is.close();
// opening database connection to MySQL server
con = DriverManager.getConnection(url, user, pass);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}