We recently had to set up one of the tomcat servers from scratch. Tomcat version is 8.0.20. Deploying a war file, now System.getProperty("mode") returns "null" where it should return PREPROD.
It should read this "mode" from a mode.properties file which is located in the webapps directory. The two lines commented out show another part of code that does not work anymore on the new tomcat server. I replaced it with code that should work.
//String pathOfWebInf = sce.getServletContext().getRealPath("WEB-INF");
//String pathOfLocalhostFile = pathOfWebInf + File.separator + "classes"
// + File.separator;
String pathOfLocalhostFile = this.getClass().getResource("/").getPath();
String mode = System.getProperty("mode");
String fileName = "localhost-oracle.properties." + mode;
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("xxx");
Properties dbProps = new EncryptableProperties(encryptor);
try
{
InputStream is = new FileInputStream(pathOfLocalhostFile + fileName);
dbProps.load(is);
} catch (Exception e)
{
throw new IOException("Could not read properties file " + pathOfLocalhostFile + fileName);
}
System.properties is related to all properties in the Computer where the JVM is running... there is no mode key defined there, that is why you get null as value....
check out all the properties in the pc by doing:
final Properties props = System.getProperties();
props.list(System.out);
and verify yourself, there is no mode key in that map...
You have to load mode.properties first, like this way
private Properties mode=null;
mode = new Properties();
mode.load(new FileInputStream(pathtoMODE));
String mode = mode.getProperty("mode");
Related
I have the following bit of code in Android. It is supposed to create a properties file and set up some properties on app init.
String androidFilePath = settingsFolderPath + File.separator + "my.properties";
File ROOT_DIR = Services.get(StorageService.class)
.orElseThrow(() -> new RuntimeException("Local storage not supported on this device!"))
.getPublicStorage("")
.orElseThrow(() -> new RuntimeException("No local storage found on this device!"));
File settingsFile = new File(ROOT_DIR, androidFilePath);
new File(settingsFile.getParent()).mkdirs();
settingsFile.createNewFile();
Properties properties = new Properties();
String public_lobby = (String) properties.getOrDefault("public_lobby",
InetAddress.getLocalHost().getHostAddress());
properties.put("public_lobby", public_lobby);
String public_lobby_port = (String) properties.getOrDefault("public_lobby_port", String.valueOf(1257));
properties.put("public_lobby_port", public_lobby_port);
OutputStream output = new FileOutputStream(settingsFile.getAbsoluteFile());
properties.store(output, null);
The problem is that when I start the app the properties file is created but never written.
I checked the my manifest and permissions and it seems to me that it is set correctly.
I do not know what to do, please help me.
So I am working in a team of people on a small school project, and we're developing java/jsp web app with apache.. I created simple properties.config file so I can store values and use them later and it looks something like this:
home_url = http://localhost:8080/to3/
to3_path = C:/Users/User2/Documents/workspace/TO-3
db_url = jdbc:mysql://localhost:3306/to3?useUnicode=true&characterEncoding=UTF-8
Problem I have is when I commit it and someone do a checkout they have to change values for url-s and paths so it fits their machine.. I heard I can make a custom properties file which will override these default values if it recognizes certain machine, but I don't know how to do it.
Thank you all in advance for your help.
Don't commit project settings. Put them in .gitignore and commit a copy of it (e.g. properties.config.sample). Make sure to keep it up to date with any new keys you add, but each developer should make their own untracked copy.
As Amadan point out you should not commit project properties. My suggestion is to create a file with .properties extension and place your properties inside. To use this file in java you can create a class like that
public class MyProperties{
private String homeUrl = "";
private String to3Path = "";
private String dbPath = "";
private final String configPath = System.getProperty("user.home") + File.separator + "my-props.properties";
public void loadProperties(){
try {
Properties prop = new Properties();
InputStream input = null;
File filePath = new File(configPath);
input = new FileInputStream(filePath);
// load a properties file
prop.load(input);
homeUrl = prop.getProperty("home_url");
to3Path = prop.getPropert("to3_path");
dbPath = prop.getProperty("db_url");
}catch (Exception e) {
e.printStackTrace();
}
}
// getters & setters
}
Then in your app you can do
MyProperties props = new MyProperties();
props.loadProperties();
String homeUrl = props.getHomeUrl();
System.getProperty("user.home") will give home path depending on the OS.
For example in windows this is path is C:\Users\yourName
This way all your co-workers can place their own properties in their personal pc inside their home path and you will be able to work without conflicts.
I'm having problems with my program on Windows, I included logging, so that I can find the specific cause of the issue. My program's JavaFX and to start it on windows I build it as .jar file.
I'm setting up a log4j FileAppender through program code, in the config-file (.../MyProject/data/configuration.txt) is the path where to have the log folder. On Mac OS X (debugged with Eclipse) everything is working fine.
If i'm starting the jar on Windows (.../MyProject/build/dist/MyProgram.jar) and see the configured log folder, i don't see any log file created. (I figured out that the config file than has to be under .../MyProject/build/dist/data/configuration.txt) If i write new subfolders to the log directory's path, the program creates them, but there's no file!
My code:
String computername = "";
try {
computername = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
}
int tid = (int)Thread.currentThread().getId();
PatternLayout playout = new PatternLayout("%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}; %p; %F:%L; " + computername + "; " + tid + "; [%t]; %m;%n");
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date datenow = new Date();
datenow.setTime(datenow.getTime());
FcManagerMain.formatteddate = dt.format(datenow);
try
{
File config = new File ("data/configuration.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader("data/configuration.txt"));
int count = 1;
String line = null;
while((line = bufferedReader.readLine()) != null)
{
if(count == 3)
{
FcManagerMain.logfolder = line;
}
count++;
}
if(isWindows())
{
File p = new File(FcManagerMain.logfolder + FcManagerMain.version);
p.mkdirs();
File pp = new File(FcManagerMain.logfolder + FcManagerMain.version + "\\" + FcManagerMain.formatteddate + ".log");
pp.createNewFile();
FileAppender fileAppender = new FileAppender(playout, pp.getAbsolutePath(), false);
loggerstatic.addAppender(fileAppender);
loggerstatic.setLevel(Level.ALL);
}
else
{
File p = new File(FcManagerMain.logfolder + FcManagerMain.version);
p.mkdirs();
File pp = new File(FcManagerMain.logfolder + FcManagerMain.version + "/" + FcManagerMain.formatteddate + ".log");
pp.createNewFile();
FileAppender fileAppender = new FileAppender(playout, pp.getAbsolutePath(), false);
loggerstatic.addAppender(fileAppender);
loggerstatic.setLevel(Level.ALL);
}
}
catch(Exception ee)
{
System.out.println(getStackTrace(ee));
}
loggerstatic is a static Logger instance (FcManagerController.loggerstatic) and every other class takes its logger from loggerstatic. I guess that's not correct, please tell me how to do!
EDIT: I have already tried different log locations to see if I don't have permission to write to that specific folders.
Thanks,
rapgru
I'd rather recommend you use the built-in configuration, i. e. adapt the log4j.properties.
Read the documentation, especially the usage of ${log} here:
# Set the name of the file
log4j.appender.FILE.File=${log}/log.out
You declare your own system variable by default and change it via jvm parameter when you start your app:
# log directory (default, 'log' directory relative to the execution path)
# you can override the default directory by setting the variable as VM option when you start the application
# example: -DMYAPP_LOG_DIR=/tmp/logs
MYAPP_LOG_DIR=./log
...
log4j.appender.debugfile.file=${MYAPP_LOG_DIR}/application.log
Then when you start your application and don't want the log file to be in the execution folder, just specify a different path via the -D option.
I'm trying to change some values in my config.properties file.There is change in values when I set them but it doesn't get saved. here is my code
public class Config {
String filename = "config.properties";
public void displayConfig() throws IOException {
Properties prop = new Properties();
InputStream input = null;
input = getClass().getClassLoader().getResourceAsStream(filename);
if (input == null) {
System.out.println("unable to find " + filename);
return;
}
prop.load(input);
System.out.println();
System.out.println(prop);
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = prop.getProperty(key);
System.out.println(key + " : " + value);
}
return;
}
public void setConfig() throws Exception {
File filename = new File("config.properties");
Properties prop = new Properties();
FileInputStream in = new FileInputStream(filename);
prop.load(in);
in.close();
FileOutputStream out = new FileOutputStream("config.properties");
prop.setProperty("db", "csv");
prop.setProperty("user", "tej");
prop.setProperty("password", "54321");
prop.store(out, null);
out.close();
System.out.println();
System.out.println(prop);
}
}
and the output when I call displayConfig,setConfig,displayConfig is like
{user=localhost, db=dtcc, password=12345}
db : dtcc
user : localhost
password : 12345
{user=tej, db=csv, password=54321, key=value}
{user=localhost, db=dtcc, password=12345}
db : dtcc
user : localhost
password : 12345
Well, that's quite expected, since displayConfig() doesn't load its properties from the same location as setConfig().
displayConfig() loads them from the resource config.properties at the root of the classpath, and setConfig loads and saves them in a file in the current directory.
BTW; even if the current directory happens to be in the classpath, I think getResourceAsStream() caches the stream content the first time it's called.
Choose your poison: either you want readable and writable files, and you should use file IO, or you want read-only resources loaded from the classpath, and you should use getResource[AsStream]. Don't mix both.
This question already has answers here:
Platform independent paths in Java
(8 answers)
Closed 3 years ago.
I have a java swing database application which needs to be run on Windows and Linux. My database connection details are stored in a XML file and I load them.
This application can load this properties on Linux properly but it is not working on Windows.
How do I load files on multiple platforms properly using Java?
This is the code:
PropertyHandler propertyWriter = new PropertyHandler();
List keys = new ArrayList();
keys.add("ip");
keys.add("database");
Map localProps = propertyWriter.read(keys, "conf" + File.separatorChar + "properties.xml", true);//if false load from the local properties
//get properties from the xml in the internal package
List seKeys = new ArrayList();
seKeys.add("driver");
seKeys.add("username");
seKeys.add("password");
Map seProps = propertyWriter.read(seKeys, "conf" + File.separatorChar + "properties.xml", true);
String dsn = "jdbc:mysql://" + (String) localProps.get("ip") + ":3306/" + (String) localProps.get("database");
jDBCConnectionPool = new JDBCConnectionPool((String) seProps.get("driver"), dsn, (String) seProps.get("username"), (String) seProps.get("password"));
File reader method:
public Map read(List properties, String path, boolean isConfFromClassPath)
{
Properties prop = new Properties();
Map props = new HashMap();
try {
if (isConfFromClassPath) {
InputStream in = this.getClass().getClassLoader().getResourceAsStream(path);
prop.loadFromXML(in);
for (Iterator i = properties.iterator(); i.hasNext();) {
String key = (String) i.next();
props.put(key, prop.getProperty(key));
}
in.close();
} else {
FileInputStream in = new FileInputStream(path);
prop.loadFromXML(in);
for (Iterator i = properties.iterator(); i.hasNext();) {
String key = (String) i.next();
props.put(key, prop.getProperty(key));
}
in.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return props;
}
If the file is in a jar file and accessed by the classpath then you should always use /.
The JavaDocs for the ClassLoader.getResource say that "The name of a resource is a '/'-separated path name that identifies the resource."
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
I'm not sure if there is the proper way, but one way is:
File confDir = new File("conf");
File propFile = new File(confDir, "properties.xml");
But in a scenario as simple as yours, I would just use /
If it's a resource located in classpath, we can load it with following snippet:
getClass().getClassLoader().getResourceAsStream(
"/META-INF/SqlQueryFile.sql")));
You can load all files on multiple platforms without any trouble.
Kindly use Matcher.quoteReplacement(File.separator) for replacing the slash.
It will works for every platform.
String fileLocation = "/src/service/files";
fileLocation = fileLocation.replaceAll("/",Matcher.quoteReplacement(File.separator));
assuming that your file is in conf/properties.xml on Linux and conf\properties.xml on Windows,
use File.pathSeparator instead of File.separator