I'm setting up a series of preferences in my Eclipse (3.5.2) application and I'm having a problem with the FileFieldEditor. I want to allow the user to specify a log file to print output to. Often, this will be a new file. But when I use the file select dialog with FileFieldEditor, it complains that the file doesn't exists ("Value must be an existing file"). Is there a way, without extending the FileFieldEditor class, to suppress this error and have Java create that file if it doesn't exist? Thanks!
When I look the source code of org.eclipse.jface.preference.FileFieldEditor, the only solution would be to extend it and write your own version of a FileFieldEditor, with:
an overwritten changePressed() method in order to keep the file path even if the file does not exists
an overwritten checkState() method in order to avoid that error message.
So I do not see a way to avoid that FileFieldEditor extension here.
Related
Using Java.util.logging's FileHandler class to create cyclic logs. However why these logs are appended with .0 extension. .1,.2,.3 etc are fine, I only do not need .0 as my extension of file, since its confusing for the customer. Any way to achieve the same?
I am using java version java version "1.8.0_144".
FileHandler fileTxt = new FileHandler(pathOfLogFile+"_%g.log",
Integer.parseInt(prop.getProperty("MAX_LOG_FILE_SIZE")),
Integer.parseInt(prop.getProperty("NO_OF_LOG_FILES")), true);
SimpleFormatter formatterTxt = new SimpleFormatter();
fileTxt.setFormatter(formatterTxt);
logger.addHandler(fileTxt);
Name of log file is LOG_0.log. requirement is to not to have _0 on the latest file, need to be simply LOG.log.
You'll have to add more information about how your are setting up your FileHandler. Include code and or logging.properties file.
Most likely you are creating multiple open file handlers and are simply not closing the previous one before you create the next one. This can happen due to bug in your code or that you are simply not holding a strong reference to the logger that holds your FileHandler. Another way to create this issue is by create two running JVM processes. In which case you have no option but to choose the location of the where the unique number is placed in your file name.
Specify the %g token and %u in your file pattern. For example, %gfoo%u.log.
Per the FileHandler documentation:
If no "%g" field has been specified and the file count is greater than one, then the generation number will be added to the end of the generated filename, after a dot.
[snip]
Normally the "%u" unique field is set to 0. However, if the FileHandler tries to open the filename and finds the file is currently in use by another process it will increment the unique number field and try again. This will be repeated until FileHandler finds a file name that is not currently in use. If there is a conflict and no "%u" field has been specified, it will be added at the end of the filename after a dot. (This will be after any automatically added generation number.)
Thus if three processes were all trying to log to fred%u.%g.txt then they might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as the first file in their rotating sequences.
If you want to remove the zero from the first file only then the best approximation of the out of the box behavior would be to modify your code to:
If no LOG_0.log file exists then use File.rename to add the zero to the file. This changes LOG.log -> LOG_0.log.
Trigger a rotation. Results in LOG_0.log -> LOG_1.log etc. Then LOG_N.log -> LOG_0.log
Use File.rename to remove the zero from the file. LOG_0.log -> LOG.log
Open your file handler with number of logs as one and no append. This wipes the oldest log file and starts your new current one.
The problem with this is that your code won't rotate based on file size during a single run.
Simply use logger name as filename (Don't include %g in it). The latest file will be filename.log. Also note that the rotated files will have the numbers as extension.
I want to add new property to an existing file. Whenever, I add the new property, the entire file gets overwritten. Is there a way to update the file and not overwrite property.
FileOutputStream fo = new FileOutputStream(PROPERTIES_FILE);
Properties pr = new Properties();
pr.setProperty("Key1", "KeyValue");
try {
pr.store(fo, " Comments");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(1) Now if I want to add a new property called Key2 and the set a value KeyValue2. Is it possible ?
(2) Also when I deploy in tomcat, only when I give the absolute path, the file is getting updated. Is there a way to find the file location at runtime. Because when I run test case, the file will be present locally and the path will be different.
(3) Is there a way to leverage classpath in anyway for this.
Thanks in advance!
**I am writing it down since I did not find clear answer for the problem mentioned **
(1) Now if I want to add a new property called Key2 and the set a value KeyValue2. Is it possible ?
**Yes it is possible. The key to understanding here is that, the properties object will be store on calling 'store' api. Here appending does not happens. The file will be overwritten by the contents of the properties object. THE API DOES NOT SUPPORT APPENDING IT.
The solution this problem will be to :
1) Load the properties from the same file
2) Update the new property or existing property
3) then store using the output stream
IN THIS WAY THE CONTENT OF THE FILE WILL NOT BE LOST**
(2) Also when I deploy in tomcat, only when I give the absolute path, the file is getting updated. Is there a way to find the file location at runtime. Because when I run test case, the file will be present locally and the path will be different.
** There are two ways to do it
1) Make sure that the file is present in the classpath. If present in the classpath, we need not give absolute path before the filename
2) Provide another class which set the path. In this way, the path can be set when running the testcases. (TESTNG/JUNIT)**
(3) Is there a way to leverage classpath in anyway for this.
** Already covered above **
Hope this helps
I am trying to rename a file in Camel when a duplicate is found. I have a directory that has x number of files and if another file is put in that folder I want the original to be renamed rather than overwritten.
I tried to use fileExists and tempFileName options but it does not solve the issue.
.to("file://"+decryptedFailed+"?delay=3000&tempFileName=tempName&fileExist=TryRename")
Is there anything wrong with how I am doing this?
From the Camel documentation:
TryRename [...] allows to try renaming the file from the temporary name to the actual name, without doing any exists check.
This is not what you want. Instead of TryRenameuse Move together with the moveExisting option:
.to("file://"+decryptedFailed+"?delay=3000&fileExist=Move&moveExisting=${file:name.noext}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}");
I would like to know whether or not there is some way of marking a file to identify whether or not the file contains x.
Consider the following example:
During a batch conversion process I am creating a log file which lists the success / failure of individual conversions.
So the process is as follows:
start conversion process
create log file named batch_XXX_yyyy_mm_dd.log
try to convert 'a'
write success to log file
try to convert 'b'
write success to log file
...
try to convert 'z'
write success to log file
close and persist log file
What I would like to be able to do is mark a file in some way that identifies whether any of the conversions logged in the file were unsuccessful.
I do not want to change the file name (visibly) and I do not want to open the file to check for a marker.
Does anyone have any ideas on how this could be achieved?
You can add file attributes in Java 7 through the java.nio.file.Files class.
So it would be possible to mark whether a file contains X using the Files.setAttribute() method:
Files.setAttribute( "path/to/file", "containsX", true );
And then check whether the file does contain X using the Files.getAttribute( ) method:
Files.getAttribute( "path/to/file", "containsX" )
If you are looking into say
file.log
create another file which will maintain this info say
file.log.status
Your status file can then contain all the information you need. It will be easier to get the status of conversion for all the files as well as easy to map back to original file given a status file.
We're recently switched over to Log4J from JUL (java.util.Logging) because I wanted to add additional log files for different logging levels.
We have the option in the program to optionally append a value and a date/time stamp to the log file name at the (for all intents and purposes) end of the program's execution.
Because JUL seemed to open and close the file as needed to write to the file, it wasn't locked and we could simply use .renameTo() to change the filename.
Now, using Log4J, that file is left open and is locked, preventing us from renaming the file(s).
I can't decide the name of the file before I configure the logging because the property file containing the options for renaming is some time after the logging is needed (this is why we renamed it at the end of the program).
Do you have any suggestions as to how this can be achieved?
Would Logback and/or SLF4J help or hinder this?
I have sort of worked around the issue by using a system parameter in the log4j properties file, setting the property and then reloading the property file.
This allows me to change the name of the log file to something else at the end of the run, and then rename the old files.
It's inelegant, and very much of a kludge, so I would like to avoid this as it also leaves these temporary files around after the run.
One surefire approach would be to implement your own log4j Appender, perhaps based on the FileAppender ( http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/FileAppender.html ). Add your own specialized API to request the file be renamed.
I haven't tried this yet, but the tact I would take would be to use the underlying API setFile(...): http://www.jdocs.com/log4j/1.2.13/org/apache/log4j/FileAppender.html#M-setFile%28String,boolean,boolean,int%29
For example:
public class RenamingFileAppender extends FileAppender {
...
/** fix concurrency issue in stock implementation **/
public synchronized void setFile(String file) {
super.setFile(file);
}
public synchronized void renameFile(String newName) {
// whole method is synchronized to avoid losing log messages
// implementation can be smarter in having a short term queue
// for any messages that arrive while file is being renamed
File currentFile = new File(this.fileName);
File newFile = new File(newName);
// do checks to ensure current file exists, can be renamed etc.
...
// create a temp file to use while current log gets renamed
File tempFile = File.createTempFile("renaming-appender", ".log");
tempFile.deleteOnExit();
// tell underlying impl to use temporary file, so current file is flushed and closed
super.setFile(tempFile.getAbsolutePath(), false, this.bufferedIO, this.bufferSize);
// rename the recently closed file
currentFile.renameTo(newFile);
// now go back to the original log contents under the new name. Note append=true
super.setFile(newFile.getAbsolutePath(), true, this.bufferedIO, this.bufferSize);
}
Consider using a shutdown hooks, and renaming the file there...
http://onjava.com/pub/a/onjava/2003/03/26/shutdownhook.html
http://www.developerfeed.com/threads/tutorial/understanding-java-shutdown-hook
http://download.oracle.com/javase/1.4.2/docs/guide/lang/hook-design.html