Where is config.properties stored ?
I can't seem to track it down. I am able to read from it so I know it exists.
I use maven for dependency management, the WAR file is built using Eclipse default build action.
I checked all the following locations in the Navigator view, Package Explorer and the WAR file:
/
/src
/WebContent
/WebContent/Web-INF
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("config.properties");
// set the properties value
prop.setProperty("os", OsDetect.getPropertyOsName());
// save properties to project root folder
prop.store(output, null);
}
catch (IOException io) {
io.printStackTrace();
}
finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I ended up putting the file in my WEB-INF/lib folder and manually edit it with the key/value properties. Placing it in the WEB-INF makes it unavailable for direct Servlet request.
To read the from the properties file I do the following :
private final String PROPERTIESPATH ="/WEB-INF/lib/config.properties";
private final Properties properties = new Properties();
private void loadProperties(ServletContextEvent context) {
....
InputStream input = context.getServletContext().getResourceAsStream(PROPERTIESPATH);
properties.load(input);
....
}
Related
This spring app performs simple file upload,
here's the controller class
#Override
public String fileUpload(MultipartFile file) {
try{
// save uploaded image to images folder in root dir
Files.write(Paths.get("images/"+ file.getOriginalFilename()), file.getBytes());
// perform some tasks on image
return "";
} catch (IOException ioException) {
return "File upload has failed.";
} finally {
Files.delete(Paths.get("images/" + file.getOriginalFilename()));
}
}
but when i build jar and runs, it throws IOException saying,
java.nio.file.NoSuchFileException: images\8c9.jpeg.
So my question is how can i add the images folder inside the jar executable itself.
Thanks.
You should provide a full path for the images folder, or save in java.io.tmpdir creating the image folder first.
But, in my opinion you should configure your upload folder from a config file for flexibility. Take a look at this.
app:
profile-image:
upload-dir: C:\\projs\\web\\profile_image
file-types: jpg, JPG, png, PNG
width-height: 360, 360
max-size: 5242880
In your service or controller, do whatever you like, may be validate image type, size etc and process it as you like. For instance, if you want thumbnails(or avatar..).
In your controller or service class, get the directory:
#Value("${app.image-upload-dir:../images}")
private String imageUploadDir;
Finally,
public static Path uploadFileToPath(String fullFileName, String uploadDir, byte[] filecontent) throws IOException {
Path fileOut = null;
try{
Path fileAbsolutePath = Paths.get(StringUtils.join(uploadDir, File.separatorChar, fullFileName));
fileOut = Files.write(fileAbsolutePath, filecontent);
}catch (Exception e) {
throw e;
}
return fileOut; //full path of the file
}
For your question in the comment: You can use java.io.File.deleteOnExit() method, which deletes the file or directory defined by the abstract path name when the virtual machine terminates. TAKE A GOOD CARE THOUGH, it might leave some files if not handled properly.
try (ByteArrayOutputStream output = new ByteArrayOutputStream();){
URL fileUrl = new URL(url);
String tempDir = System.getProperty("java.io.tmpdir");
String path = tempDir + new Date().getTime() + ".jpg"; // note file extension
java.io.File file = new java.io.File(path);
file.deleteOnExit();
inputStream = fileUrl.openStream();
ByteStreams.copy(inputStream, output); // ByteStreams - Guava
outputStream = new FileOutputStream(file);
output.writeTo(outputStream);
outputStream.flush();
return file;
} catch (Exception e) {
throw e;
} finally {
try {
if(inputStream != null) {
inputStream.close();
}
if(outputStream != null) {
outputStream.close();
}
} catch(Exception e){
//skip
}
}
I'm executing a jar file which reads configs from a config file outside of /home/user/xxx/testFolder/jarfile, the path of config file is /opt/xxx/conf/global_config.cfg.
However, I'm able to access files inside the jar, so I assume the error is due to the file not being found.
Below is my code:
public Properties createProperties(){
Properties p = null;
ClassLoader cl = this.getClass().getClassLoader();
try (InputStream stream = cl.getResourceAsStream("/opt/xxx/conf/global_config.cfg")) {
p = new Properties();
BufferedInputStream bis = new BufferedInputStream(stream);
p.load(bis); // this is throwing the error
System.out.println(p.toString());
} catch (IOException e) {
e.printStackTrace();
}
return p;
}
What is the correct way of getting a file regardless of its path in a Linux system?
cl.getResourceAsStream("/opt/xxx/conf/global_config.cfg")
expects the resource to be available in relation to the class location. So, it will search as a relative path to the class inside the JAR. But the path /opt/xxx/conf/global_config.cfg is a absolute disk path, and for reading it , you need to use the FileInputStream
public Properties createProperties(){
Properties p = null;
ClassLoader cl = this.getClass().getClassLoader();
try (InputStream stream =new FileInputStream("/opt/xxx/conf/global_config.cfg")) {
p = new Properties();
p.load(stream);
System.out.println(p.toString());
} catch (IOException e) {
e.printStackTrace();
}
return p;
}
I will use user.properties to overwrite some properties in jmeter.properties.
Overwriting the properties summariser.out in jmeter.properties:
in jmeter.properties
summariser.out=true
in user.properties
summariser.out=false
In the apache doc is written:
Note: You can define additional JMeter properties in the file defined
by the JMeter property user.properties which has the default value
user.properties. The file will be automatically loaded if it is found
in the current directory or if it is found in the JMeter bin
directory. Similarly, system.properties is used to update system
properties.
so, my user.properties is in /bin and I the property in jmeter.properties -> user.properties=user.properties.
I tried also to load manually like:
Properties props = new Properties();
InputStream is = getTempInputStream(userPropTempFilePath);
props.load(is);
is.close();
That all has no effect.
Some idea how to load user.properties in java and to check if the properties are loaded?
Thats the solution:
String userProp = JMeterUtils.getPropDefault("user.properties", "");
if (userProp.length() > 0) {
FileInputStream fis = null;
try {
File file = JMeterUtils.findFile(userProp);
if (file.canRead()) {
log.info("Loading user properties from: "
+ file.getCanonicalPath());
fis = new FileInputStream(file);
Properties tmp = new Properties();
tmp.load(fis);
jmeterProps.putAll(tmp);
LoggingManager.setLoggingLevels(jmeterProps);//Do what would be done earlier
}
} catch (IOException e) {
log.warn("Error loading user property file: " + userProp, e);
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException ex) {
log.warn("There was problem closing file stream", ex);
}
}
}
I have a custom java server. It uses an external xml config file.
I have some command line options to help the user, the usual stuff for showing a help file, setting ports, etc...
I've recently added a command to generate a default config file for the server. It's an xml file. After researching my options, packing a default xml file in the jar seemed to be the way to go, but I'm obviously missing something.
So far my code looks like this:
public class ResourceLoader {
private File outFile = null;
private Reader fileReader = null;
private Writer fileWriter = null;
private InputStream is = null;
private char[] buffer = null;
public ResourceLoader() {
outFile = new File("default-server.xml");
}
public void generateDefaultServerXml() {
is = ResourceLoader.class.getResourceAsStream("/default-server.xml");
if (is == null) {
System.out.println("Configuraiton File generation failed. The InputStream is null.");
} else {
fileReader = new InputStreamReader(is);
}
buffer = new char[4096];
FileOutputStream fos;
try {
fos = new FileOutputStream(outFile);
fileWriter = new OutputStreamWriter(fos);
while (fileReader.read(buffer) != -1) {
fileWriter.write(buffer, 0, buffer.length);
fileWriter.flush();
buffer = new char[4096];
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fileReader.close();
fileWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The code above works perfectly fine when I run it in eclipse, but intitially, after I export the jar file the server could not locate the default-server.xml file when I run the command from the terminal.
The file itself is located in a package called main.resources along with some other config files and the above class.
I have since moved the ResourceLoader.class to another package. After doing that the server seems to find the xml file in the main.resources package (InputStream is not null) but the resulting generated default-server.xml file is empty.
Again, this all works perfectly well when I run it in eclipse, it's only after I export the project and try issue the command from the terminal that the process fails. What am I doing wrong?
The above class is instantiated, and the generateDefaultServerXml() is called, from the main method of the server.
EDIT: My path for writing default-server.xml was slightly wrong. Now that I've adjusted it the code works exactly as expected when I run it in Eclipse. The resource is read in the correct way, and written to the file in the correct location. But it still doesn't work when I try the same thing from the jar file.
You current line ResourceLoader.class.getResourceAsStream("/default-server.xml") means that you are trying to load a resource named default-server.xml from the root of your classpath, or put simpler, from the root of your jar file. This means that xml file should NOT be in any package inside the jar file.
When you assemble your jar file and then run jar tf my.jar on it, do you see your default-server.xml file? Does it reside in some package or in the root of the jar file?
The problem here is since you are packaging the application as a jar. The procedure to call an external resource is quite different.
You need to have a folder structure as
root
--your jar
--your xml file
Your code shallwork if the application is using an default-server.xml file inside the jar.
Otherwise, Replace below line in your code if you want to use an external default xml file.
is = new FileInputStream("./default-server.xml");
If the output file you want at root location the use below code
public ResourceLoader() {
outFile = new File("./default-server.xml");
}
Alternate code as per discussion
public class ResourceLoader {
public void generateDefaultServerXml() {
try {
String defaultxmltext =readFileToString("/default-server.xml");
writeFileFromInputString(defaultxmltext);
} catch (IOException e) {
//exception
}
}
public static void writeFileFromInputString(String everything) throws IOException {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("./default-server.xml"))) {
everything = everything.replaceAll("\n", System.getProperty("line.separator"));
writer.write(everything);
}
}
public static String readFileToString(String path) throws IOException {
String everything = null;
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
everything = sb.toString();
}
return everything;
}
}
Hope this helps
consider your file located on src/main/resources try this
getClass().getClassLoader().getResource(fileName)
well as far as i can see your main problem is that you are passing the wrong path, since you mentioned the xml is under main.resources you will need to add this to the path when trying to load the file, here is a sample piece of code that should work for you
Scanner sc = null;
PrintWriter writer = null;
try {
sc = new Scanner(getClass().getResourceAsStream("main/resources/server.xml"));
writer = new PrintWriter("./default_server.xml", "UTF-8");
while(sc.hasNextLine()) {
writer.println(sc.nextLine());
}
} catch (Exception e) {
} finally {
if(sc != null) {
sc.close();
}
if(writer != null){
writer.close();
}
}
there is a text file that an application produces, I would like to take that file and read it as strings in my application. How can I achieve that, any help would be grateful. Both applications are my applications so I can get the permissions.
Thank you!
This is possible using the standard android-storage, where all the user's files are stored too:
All you need to do is to access the same file and the same path in both applications, so e.g.:
String fileName = Environment.getExternalStorageDirectory().getPath() + "myFolderForBothApplications/myFileNameForBothApplications.txt";
Where myFolderForBothApplications and myFileNameForBothApplications can be replaced by your folder/filename, but this needs to be the same name in both applications.
Environment.getExternalStorageDirectory() returns a File-Object to the common, usable file-directory of the device, the same folder the user can see too.
By calling the getPath() method, a String representing the path to this storage is returned, so you can add your folder/filenames afterwards.
So a full code example would be:
String path = Environment.getExternalStorageDirectory().getPath() + "myFolderForBothApplications/";
String pathWithFile = path + "myFileNameForBothApplications.txt";
File dir = new File(path);
if(!dir.exists()) { //If the directory is not created yet
if(!dir.mkdirs()) { //try to create the directories to the given path, the method returns false if the directories could not be created
//Make some error-output here
return;
}
}
File file = new File(pathWithFile);
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
//File couldn't be created
return;
}
Afterwards, you can write in the file or read from the file as provided e.g. in this answer.
Note that the file stored like this is visible for the user and my be edited / deleted by the user.
Also note what the JavaDoc for the getExternalStorageDirectory() says:
Return the primary external storage directory. This directory may not currently be accessible if it has been mounted by the user on their computer, has been removed from the device, or some other problem has happened. You can determine its current state with getExternalStorageState().
I do not know if this is the best/safest way to fix your problem, but it should work.
You can save the text file from your assets folder to anywhere in the sdcard, then you can read the file from the other application.
This method uses the getExternalFilesDir, that returns the absolute path to the directory on the primary shared/external storage device where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(Environment.getExternalStorageDirectory(), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
And to read:
File dir = Environment.getExternalStorageDirectory();
File yourFile = new File(dir, "path/to/the/file/inside/the/sdcard.ext");