J'ai essayé la réponse de pushy ci-dessus et ça a marché pour la plupart. Cependant, dans certaines circonstances, je verrais bien cette exception :
java.lang.String cannot be cast to java.lang.ProcessEnvironment$Variable
Il s'avère que cela se produit lorsque la méthode a été appelée plus d'une fois, en raison de l'implémentation de certaines classes internes de l'application ProcessEnvironment.
Si le setEnv(..)
est appelée plus d'une fois, lorsque les clés sont récupérées à partir de la base de données de l'UE. theEnvironment
ils sont maintenant des chaînes de caractères (ayant été placées en tant que chaînes de caractères par la première invocation de la fonction setEnv(...)
) et ne peut être converti en type générique de la carte, Variable,
qui est une classe interne privée de ProcessEnvironment.
Une version corrigée (en Scala), est ci-dessous. J'espère qu'il ne sera pas trop difficile de la transposer en Java.
def setEnv(newenv: java.util.Map[String, String]): Unit = {
try {
val processEnvironmentClass = JavaClass.forName("java.lang.ProcessEnvironment")
val theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment")
theEnvironmentField.setAccessible(true)
val variableClass = JavaClass.forName("java.lang.ProcessEnvironment$Variable")
val convertToVariable = variableClass.getMethod("valueOf", classOf[java.lang.String])
convertToVariable.setAccessible(true)
val valueClass = JavaClass.forName("java.lang.ProcessEnvironment$Value")
val convertToValue = valueClass.getMethod("valueOf", classOf[java.lang.String])
convertToValue.setAccessible(true)
val sampleVariable = convertToVariable.invoke(null, "")
val sampleValue = convertToValue.invoke(null, "")
val env = theEnvironmentField.get(null).asInstanceOf[java.util.Map[sampleVariable.type, sampleValue.type]]
newenv.foreach { case (k, v) => {
val variable = convertToVariable.invoke(null, k).asInstanceOf[sampleVariable.type]
val value = convertToValue.invoke(null, v).asInstanceOf[sampleValue.type]
env.put(variable, value)
}
}
val theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment")
theCaseInsensitiveEnvironmentField.setAccessible(true)
val cienv = theCaseInsensitiveEnvironmentField.get(null).asInstanceOf[java.util.Map[String, String]]
cienv.putAll(newenv);
}
catch {
case e : NoSuchFieldException => {
try {
val classes = classOf[java.util.Collections].getDeclaredClasses
val env = System.getenv()
classes foreach (cl => {
if("java.util.Collections$UnmodifiableMap" == cl.getName) {
val field = cl.getDeclaredField("m")
field.setAccessible(true)
val map = field.get(env).asInstanceOf[java.util.Map[String, String]]
// map.clear() // Not sure why this was in the code. It means we need to set all required environment variables.
map.putAll(newenv)
}
})
} catch {
case e2: Exception => e2.printStackTrace()
}
}
case e1: Exception => e1.printStackTrace()
}
}
1 votes
System.getEnv() est destiné à être universel, certains environnements n'ont même pas de variables d'environnement.
17 votes
Pour tous ceux qui en ont eu besoin dans le cadre de tests unitaires : stackoverflow.com/questions/8168884/
1 votes
Pour Scala, utilisez ceci : gist.github.com/vpatryshev/b1bbd15e2b759c157b58b68c58891ff4