If my application is run by root user, creating log file by root. So, if the app is run by another users, display 'permission denied'.
There are the logs in /opt/myapp/logs/ .
I want to set permission for log file of log4j programmatically (May be using log4j configuration) (All user should write the log file. To permit as chmod 766). Is it possible?
Writing logs to single folder will require to manually set log file name and change log folder permissions.
If you need to run your application from many users you will likely should use user home (or sub folder) to write logs.
According to the Filesystem Hierarchy Standard, logs must be put in /var/log. You can avoid clutter this folder by creating a /var/log/myapp folder, where you'll put your logs. Ensure the folder and its contents are chmod 666, or better, 766.
This is the standard used by Apache, for example.
Related
I have a need to load an external file into the classpath using Play Framework 2.3 (Java)
Stipulations:
The external file cannot live inside my Play app (i.e. the /conf and /lib directories, etc. are not an option)
The file needs to be a .properties or a .conf file so I can specify property values
Here's my scenario:
I have a custom JAR that has some code which is looking for a specific file (let's call it myproperties.properties) in the classpath when being used. The way that I'm attempting to find myproperties.properties is by doing this inside a class that resides inside that custom JAR:
ClassLoader classLoader = com.my.package.MyCustomJavaClass.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("/path/to/myproperties.properties");
I have access to change the properties file name and the path to it inside the JAR.
My Play Framework App (using Java) has this custom JAR in it's /lib folder, so it gets automatically added to the classpath (this is tested and works correctly). My Play App calls MyCustomJavaClass when it first loads the / route (index route), so the class loader and input stream code above gets kicked off when I hit my play app in the browser.
Problem:
I have not been successful in my attempts to load /path/to/myproperties.properties into the classpath when starting the Play App in a way that my code in the custom JAR can see it.
I've been attempting to start play with the classpath command like so in an attempt to feed the JVM the external file:
activator start -J-classpath "-J-classpath:/path/to/myproperties.properties"
I'm adding -J-classpath; to the beginning of the path in an attempt to copy everything that's currently in the classpath and then just adding my single, external file. However, doing this doesn't seem to be working (i.e. my inputStream is null).
Questions:
Am I doing the activator start -J-classpath command correctly when starting the play app? Other variations in an attempt to copy the existing classpath first were not allowing the play app to start, but this command at least starts my app.
Reference (Specifying additional JVM arguments): https://www.playframework.com/documentation/2.3.x/ProductionConfiguration
What are some other ways that I could possibly get this done? I've explored overriding the application.conf file using activator start -Dconfig.file=/path/to/application-override.conf and putting my properties inside the new application-override.conf file. However, it doesn't seem to put that file into the classpath for MyCustomJavaClass to find using the Class Loader. Maybe I'm doing this command incorrectly as well?
Is it possible that somehow the Play Framework classpath is separate from the classpath that my custom JAR is seeing? I've been under the assumption that it's all in one JVM and classpath.
here's the solution I came up with, hopefully it helps someone else out there:
in my "upper environments" (AWS servers) where my play app is deployed, I put an application-override.conf file in the conf folder in the play framework app directory
the application-override.conf is the exact same as my application.conf but I have some custom properties in both whose values are different in each environment that the play app lives on
my play framework app is in a git repo, which is cloned on each upper environments, so I added application-override.conf to the .gitignore (I don't want it checked it to the repo so it only lives on the servers)
when starting the play app, I now use activator start "-Dconfig.trace=loads -Dconfig.file=conf/application-override.conf". this will override the application.conf file with application-override.conf and application-override.conf will be in the JVM classpath that play uses to run the app (since it's in the conf directory). -Dconfig.trace=loads spits out more logging to let you know if the .conf file was loaded properly or not; it's not a necessary flag if everything is working properly.
on the java side, in my custom JAR, I can now do the following:
Properties properties;
InputStream stream;
ClassLoader classLoader = com.my.package.MyCustomJavaClass.class.getClassLoader();
// first, look for application-override.conf in the classpath (upper environments)
stream = classLoader.getResourceAsStream("application-override.conf");
// if null, check for application.conf (local environment)
if (stream == null) {
stream = classLoader.getResourceAsStream("application.conf");
}
properties = new Properties();
properties.load(stream);
stream.close();
other notes:
I thought about doing a symlink/softlink in the conf directory and put the application-override.conf file somewhere else on my environment, but prior to Play 2.4, you can't have symlinks in the conf directory, so I just put the actual application-override.conf file in the conf folder
The application-override.conf file has different property values for each "upper environment", otherwise I would have just delivered a single override file to the git repo. And in the custom JAR, I didn't want to put in logic that looked for varying file names like dev-override.conf, pre-prod-override.conf, prod-override.conf, etc. I wanted a single upper environments override file.
I didn't have success with the -classpath=/path/to/myproperties.properties or -J-classpath=/path/to/myproperties.properties commands in conjuction with activator start. nor did I have success with attempting to append to the classpath, e.g. activator start -J-classpath=-J-classpath:/path/to/myproperties.properties or other similar combinations
going the route of putting properties in an application-override.conf file actually killed two birds with one stone for me because I've been wanting to make some environment specific changes by having overriding .conf files on each of my environments as well as custom properties
the HOCON format of the .conf files required me to put double quotes around my property values due to the nature of my property values. when reading in those properties in Java, the quotes were still there for me, so I had to do an str.replace("\"","") when reading in those properties
I am creating an application for Android which enables users to create encrypted LUKS partitions and then mount them to given directories on external memory.
For the partition to be usable I create an ext2 file system using the Busybox mkfs.ext2 command. The problem occurs once a user tries to create a file/directory at the root of the partition. For some reason it is impossible to create a file through Java as the "File.mkdirs()" method fails. However, it is possible to create this file through the command-line. And this error occurs only when at the root of the partition (i.e if I create a folder through the command line I am then able to create files within that folder through Java). Also, I am able to create a file if I create a vfat file system instead of ext2.
Any help would be greatly appreciated.
Harry
EDIT
Fixed. I was mounting the file system as root
My final solution to this problem was to create a vfat file system rather than ext2 as vfat doesn't have permissions etc... This worked for me as I did not need the extra security of permissions. However, if you need an ext2 file system which you need to mount as root but want it to be useable by other users I recomment looking into the mount ownmask option (man mount).
I am using log4j in Eclipse for logging messages in a java desktop application. I want that the log should be created in a specific folder (Specifically, in the folder which contains source folder 'src' and classes folder 'bin').
Is it possible to set this in log4j.properties? How to ensure that log is created at this location only?
I would go with Saket's reply. But instead of hardcoding the location its always better to have a relative path.
If you started your application from a main method from a class called Launcher for example and this is the structure of your Eclipse Project directory:
Java Project
src
bin
Then just give your location to be
log4j.appender.R.File=./log/Logfile.log
This will create the file under a directory log:
Java Project
src
bin
log
LogFile.log
Hope you got it..
:)
Assuming you are using the RollingFileAppender, you could set something like this in your log4j.properties file (below I am setting C:/myapp/src/mylog.log as my target location - you can change this to your desired location):
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=C:/myapp/src/mylog.log
... (other configurations)
...
Yes it is possible to set it in property file. One example is:
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=D:/myapp/mylog.log
log4j.appender.rollingFile.MaxFileSize=2MB
log4j.appender.rollingFile.MaxBackupIndex=2
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%p %t %c - %m%n
log4j.appender.rollingFile.File=D:/myapp/mylog.log can be modified to any path on your disk.
It is not good to create log in a project folder since it gets bigger and bigger in size. Rather you can create it in user directory from which your application is running.
Eg: should be ${user.home}/appName/MyWEB.log , user generally has right to write in home dir
works for both windows and linux environment.
I need to access a file for some data in weblogic. I have this in my code,
File file = new File("myfile.csv");
When I run the code I get "File Not Found" error.
Where is the code actually looking for the file? I placed the code in a few different locations, but I cant get it to work.
If the file is at the root of your application's classpath, you can use getClass().getResource("myfile.csv");. If it's within a subdirectory, provide that path information in addition to the filename.
Try using the full path to access the file. For example "/usr/local/blah/myfile.csv"
The current directory for a running WebLogic Server instance is typically the root directory of the domain.
This is the parent directory under which you can find the 'config' and 'servers' subdirectories.
I want to create an ini file to store some settings for my application. Is it a good idea to find where the jar file is located and create an ini file there? If yes, then how can I find the location of the jar file?
But if you know a better solution for something like this, I would like to hear some of them.
EDIT: I'm using mac and I want to run the same application in windows. I could write something in the System.getProperty("user.home") directory, but I want to keep the system clean, if the user decides to remove the app. There is no a better way to store the settings file, for example in the same directory with the application?
You can locate your application directory using the ClassLoader. See: Java: finding the application directory. Rather than an .INI file, use a .properties file - you can load and save this via the Properties class.
As others have noted, you should not write user settings to your application directory. What if the user does not have write access to the application directory? What if your application is being used by multiple users on the same system at the same time? Neither of these situations are unusual, even on Windows.
You might still want to load some settings from the application directory - perhaps the administrator has configured default settings there.
A common convention is to save user settings to the user's home directory:
/home/user/.eclipse
C:\Documents and Settings\User\.eclipse
Although this means you might leave stray files behind, this can be beneficial if the user re-installs the app. Document such things in a README. Here is how to create and get a reference to the directory:
public static File getSettingsDirectory() {
String userHome = System.getProperty("user.home");
if(userHome == null) {
throw new IllegalStateException("user.home==null");
}
File home = new File(userHome);
File settingsDirectory = new File(home, ".myappdir");
if(!settingsDirectory.exists()) {
if(!settingsDirectory.mkdir()) {
throw new IllegalStateException(settingsDirectory.toString());
}
}
return settingsDirectory;
}
On unix-like operating systems, starting the directory name with a period (".myappdir") will make the directory hidden. On Windows, it will be located below My Documents, so users will not see the directory unless they go looking for it.
If the settings are only written by your application (rather than edited manually), consider using the Preferences API.
You should not be storing temp files in the install directory of an application. Remember, the user running the application may not have write access to that directory. The safest place to put stuff like that is in C:\Documents and Settings\username\Application Data\ApplicationName folder (adjusting the name as necessary).
That said, however, I would probably store that type of stuff in the registry instead of a file on their computer. (But, that's just me.)
Typically Java programmers don't use .ini files, but .properties files (different format). You can use the java.lang.Properties class as a nice programmatic wrapper if you do.
While you can get the location of your jar file by calling getProtectionDomain().getCodeSource().getLocation() on your class's .class member, I do not recommend that you do this.
I would instead write the file to the System.getProperty("user.home") directory - the users' home directory, or if it is truly temporary, System.getProperty("java.io.tmpdir")
It depends whether your ini needs to be human readable/writable under normal circumstances. If not, you can use a properties file rather than an ini file, and store it in the "user" directory.
As for finding the jar file, you would have to find the ClassLoader for a class known to be loaded from the jar, check that it was the appropriate type of ClassLoader (ie that it's really been loaded from a jar), and you can extract the path from that. I can probably dig out the code to do this if that's really what you want. I wouldn't necessarily recommend it.
EDIT The user.home property will give you the user directory, which you can safely use.
The idea with the .properties file instead of the INI file is good. Also, if you store some sensitive data in there, you may consider encrypting it. Check this out:
https://www.owasp.org/index.php/How_to_encrypt_a_properties_file
or this:
encrypt and decrypt property file value in java