Create A File in the WebContent Folder From Java - java

I wanted to know how to create a file in the WebContent folder of a dynamic web project using Java?
The basic question remaining is how to get the path of the WebContent folder.
Note: No servlet is to be used!
Edit:
Okay, i am trying to create a new xml file from java method. I want the file to be created in the WebContent folder so that the file is created even when the application is deployed.
I am using Jboss, maven, JSF to create the dynamic web project. I need the xml file to pass data to highcharts. Please note that i will be using this method only.
Overview:
Create xml file on request
XML file to created in the WebContent folder itself
Use this xml file to pass data

Glassfish solution.
AbstractSearchPageBean - any of your class
private static final String WEB_INF = "WEB-INF";
public static String getWebPath() {
final String webInfPath = getWebInfPath();
return webInfPath.substring(0, webInfPath.indexOf(WEB_INF) - 1);
}
public static String getWebInfPath() {
String filePath = "";
java.net.URL url = AbstractSearchPageBean.class.getResource("AbstractSearchPageBean.class");
if (url != null) {
String className = url.getFile();
filePath = (className.contains(WEB_INF)) ? className.substring(0, className.indexOf(WEB_INF) + WEB_INF.length()) : className;
}
return filePath.replace("%20", " ");
}
// Create file in webapp/xml directory
private void createXmlFile(String xml) {
try {
String fileName = System.currentTimeMillis() + ".xml";
File file = new File(Settings.getWebPath() + File.separatorChar + "xml" + File.separatorChar + fileName);
logger.debug("parseXML(): Creating file: " + file.getAbsolutePath());
if (file.createNewFile()) {
FileWriter fw = new FileWriter(file);
fw.write(this.parseXML(xml));
fw.flush();
fw.close();
logger.debug("parseXML(): file saved to the: " + Settings.getAPPLICATION_DOMAIN() + '/' + fileName);
} else {
logger.warn("parseXML(): Can't create file: " + file.getAbsolutePath());
}
} catch (IOException ioe) {
logger.error("parseXML(): Bad save file: ", ioe);
}
}

Related

Java FileWriter class - java.io.FileNotFoundException: * no such file or directory -Ubuntu

I am using this method to generate some turtle files .ttl in a sub-directory of my project:
public static void write(int id, int depth){
try {
FileWriter fw = null;
switch (getName()){
case ("KG1"):
fw = new FileWriter("WWW/KG1/" + depth + "/" + id + ".ttl");
break;
case ("KG2"):
fw = new FileWriter("WWW/KG2/" + depth + "/" + id + ".ttl");
}
// Write something
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
But I am having this exception when I have put my project in Ubuntu (it is still working fine in Windows) in the java class FileWriter:
java.io.FileNotFoundException: /WWW/KG1/2/0.ttl (No such file or directory)
I am using Eclipse Neon for both OSs, but it seems that Ubuntu is not happy about it.
Here is what I have tried so far:
Adding write permissons to ALL files and directories under the main project directory
Using absolute path instead of relative path, by using System.getProperty("usr.dir"), and plotting all the path string I am giving to FileWriter, but it does not work.
Any advice?
Thanks!
You can make things easier for yourself by using Path and File objects. Here is a version that optionally creates the wanted directory if it doesn't exist
Path path = Paths.get("WWW", "KG1", String.valueOf(depth));
try {
Files.createDirectories(path);
FileWriter fw = new FileWriter(new File(path.toFile(), id + ".ttl"));
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
Note that I intentionally skipped the switch to simplify the answer
I would try using File.separator and make sure the parent directory exists.
Here is an example (may have syntax issues).
final String WWW = "WWW";
final String KG1 = "KG1";
final String KG2 = "KG2";
final String extension = ".ttl";
int id = 1;
int depth = 1;
String filePath = "." // current dir
+ File.separator
+ WWW
+ File.separator
+ KG1
+ File.separator
+ depth
+ File.separator
+ id
+ extension;
File file = new File(filePath);
// make sure parent dir exists (else created)
file.getParentFile().mkdirs();
FileWriter writer = new FileWriter(file);

Cannot read file via docker container

I have a spring-boot application and I have some files placed inside /src/main/java/resources which I am trying to read it in my code. When the same code tries to read from docker container it says file does not exist. The same code works perfectly fine via localhost
The files are under /src/main/java/resources/data folder and this is my code which tries to read the file
private String getJson(String folderName, String id, StringBuilder sb) throws Exception {
String responseJson = null;
String filePath = "data" + File.separator + folderName + File.separator + id + ".json";
LOG.info("printing filePath : " + filePath);
LOG.info("printing id : " + id);
File f = new File(filePath);
// if(f.exists()){
try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
LOG.info("printing inputStream : " + inputStream);
if (inputStream != null) {
responseJson = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
}
if (responseJson == null || responseJson.isEmpty()) {
LOG.info("json response is null : ");
throw new JsonNotFoundException(Constant.JSON_NOT_FOUND);
}
sb.append(responseJson);
} catch (IOException e) {
LOG.info("IO exception : ");
throw new IOException(e);
} catch (Exception e) {
LOG.info(" exception : ");
throw new Exception(e);
}
// }
// else{
// LOG.info("file doesnt exists : " + filePath);
// }
return sb.toString();
}
An example for the file path : src/main/resources/data/get-products/1420-17612-82.json
Docker file content
{
"commands":
[
"rm -rf .tmp",
"git clone git#github.com:{orgnname}/{test-service.git} -b COECP-973-Configure-logging-mechanism-for-Service .tmp/test-service",
"docker build .tmp/test-service/.docker/build/db -t local/test-service/db",
"docker build .tmp/test-service -t local/test-service/app"
]
}
So... you messed path for File and for resources from class path. What is the reason to have File f = new File(filePath);?
Here are things:
If you use File - files must be available to the JVM and as long as you use relative path like data\folderxxx\filexxx.json it must be available in container file system. I.e. data folder must be placed in image or mounted from outside exactly into directory from where JVM runs
If you use ClassLoader and ResourceAsStream root of your data directory must be defined in class path for JVM or be in Jar file - it is a root in classpath as well. Check your jar file - if data directory is in root of jar - all fine and files will be available by this.getClass().getClassLoader().getResourceAsStream(filePath), but not for new File(filePath)!
if not - make it happen or update your filePath for ResourceAsStream accordingly.
I have had faced the same issue earlier, though our requirement got more complex over time, but the following code should solve your problem:
ClassPathResource cp = new ClassPathResource("relative_path_to_file");
File f = null;
if (cp.exists())
f = cp.getFile();

Create directory in Java but don't throw error if it already exists [duplicate]

The condition is if the directory exists it has to create files in that specific directory without creating a new directory.
The below code only creates a file with the new directory but not for the existing directory . For example the directory name would be like "GETDIRECTION":
String PATH = "/remote/dir/server/";
String fileName = PATH.append(id).concat(getTimeStamp()).append(".txt");
String directoryName = PATH.append(this.getClassName());
File file = new File(String.valueOf(fileName));
File directory = new File(String.valueOf(directoryName));
if (!directory.exists()) {
directory.mkdir();
if (!file.exists() && !checkEnoughDiskSpace()) {
file.getParentFile().mkdir();
file.createNewFile();
}
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(value);
bw.close();
Java 8+ version:
Files.createDirectories(Paths.get("/Your/Path/Here"));
The Files.createDirectories() creates a new directory and parent directories that do not exist. This method does not throw an exception if the directory already exists.
This code checks for the existence of the directory first and creates it if not, and creates the file afterwards. Please note that I couldn't verify some of your method calls as I don't have your complete code, so I'm assuming the calls to things like getTimeStamp() and getClassName() will work. You should also do something with the possible IOException that can be thrown when using any of the java.io.* classes - either your function that writes the files should throw this exception (and it be handled elsewhere), or you should do it in the method directly. Also, I assumed that id is of type String - I don't know as your code doesn't explicitly define it. If it is something else like an int, you should probably cast it to a String before using it in the fileName as I have done here.
Also, I replaced your append calls with concat or + as I saw appropriate.
public void writeFile(String value){
String PATH = "/remote/dir/server/";
String directoryName = PATH.concat(this.getClassName());
String fileName = id + getTimeStamp() + ".txt";
File directory = new File(directoryName);
if (! directory.exists()){
directory.mkdir();
// If you require it to make the entire directory path including parents,
// use directory.mkdirs(); here instead.
}
File file = new File(directoryName + "/" + fileName);
try{
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(value);
bw.close();
}
catch (IOException e){
e.printStackTrace();
System.exit(-1);
}
}
You should probably not use bare path names like this if you want to run the code on Microsoft Windows - I'm not sure what it will do with the / in the filenames. For full portability, you should probably use something like File.separator to construct your paths.
Edit: According to a comment by JosefScript below, it's not necessary to test for directory existence. The directory.mkdir() call will return true if it created a directory, and false if it didn't, including the case when the directory already existed.
Trying to make this as short and simple as possible. Creates directory if it doesn't exist, and then returns the desired file:
/** Creates parent directories if necessary. Then returns file */
private static File fileWithDirectoryAssurance(String directory, String filename) {
File dir = new File(directory);
if (!dir.exists()) dir.mkdirs();
return new File(directory + "/" + filename);
}
I would suggest the following for Java8+.
/**
* Creates a File if the file does not exist, or returns a
* reference to the File if it already exists.
*/
public File createOrRetrieve(final String target) throws IOException {
final File answer;
Path path = Paths.get(target);
Path parent = path.getParent();
if(parent != null && Files.notExists(parent)) {
Files.createDirectories(path);
}
if(Files.notExists(path)) {
LOG.info("Target file \"" + target + "\" will be created.");
answer = Files.createFile(path).toFile();
} else {
LOG.info("Target file \"" + target + "\" will be retrieved.");
answer = path.toFile();
}
return answer;
}
Edit: Updated to fix bug as indicated by #Cataclysm and #Marcono1234. Thx guys:)
code:
// Create Directory if not exist then Copy a file.
public static void copyFile_Directory(String origin, String destDir, String destination) throws IOException {
Path FROM = Paths.get(origin);
Path TO = Paths.get(destination);
File directory = new File(String.valueOf(destDir));
if (!directory.exists()) {
directory.mkdir();
}
//overwrite the destination file if it exists, and copy
// the file attributes, including the rwx permissions
CopyOption[] options = new CopyOption[]{
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES
};
Files.copy(FROM, TO, options);
}
Simple Solution using using java.nio.Path
public static Path createFileWithDir(String directory, String filename) {
File dir = new File(directory);
if (!dir.exists()) dir.mkdirs();
return Paths.get(directory + File.separatorChar + filename);
}
If you create a web based application, the better solution is to check the directory exists or not then create the file if not exist. If exists, recreate again.
private File createFile(String path, String fileName) throws IOException {
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource(".").getFile() + path + fileName);
// Lets create the directory
try {
file.getParentFile().mkdir();
} catch (Exception err){
System.out.println("ERROR (Directory Create)" + err.getMessage());
}
// Lets create the file if we have credential
try {
file.createNewFile();
} catch (Exception err){
System.out.println("ERROR (File Create)" + err.getMessage());
}
return file;
}
A simple solution using Java 8
public void init(String multipartLocation) throws IOException {
File storageDirectory = new File(multipartLocation);
if (!storageDirectory.exists()) {
if (!storageDirectory.mkdir()) {
throw new IOException("Error creating directory.");
}
}
}
If you're using Java 8 or above, then Files.createDirectories() method works the best.

How to load a properties file from the root directory?

I am currently loading a properties file like this:
private Properties loadProperties(String filename) throws IOException{
InputStream in = ClassLoader.getSystemResourceAsStream(filename);
if (in == null) {
throw new FileNotFoundException(filename + " file not found");
}
Properties props = new Properties();
props.load(in);
in.close();
return props;
}
However, at the moment my file lays at the scr\user.properties path.
But when I want to write to a properties file:
properties.setProperty(username, decryptMD5(password));
try {
properties.store(new FileOutputStream("user.properties"), null);
System.out.println("Wrote to propteries file!" + username + " " + password);
That piece of code generates me a new file at the root folder level of my project.
BUT I want to have one file to write\read.
Therefore how to do that?
PS.: When I want to specify the path I get "Not allowed to modify the file..."
The reason a new file is created because you are trying to create a new file when you are writing. You should first get handle to the user.properties that you want to write to as File object and then try to write to it.
The code would look something along the lines of
properties.setProperty(username, decryptMD5(password));
try{
//get the filename from url class
URL url = ClassLoader.getSystemResource("user.properties");
String fileName = url.getFile();
//write to the file
props.store(new FileWriter(fileName),null);
properties.store();
}catch(Exception e){
e.printStacktrace();
}

How do i get the absolute path of .java file from inside the file?

I want to create a new file at the same package of the current class.
FileOutputStream fileOut = new FileOutputStream(YYY);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(this);
what are the correct YYY for that purpose?
I tried this:
FileOutputStream fileOut = new FileOutputStream("myObject");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(this);
but the "myObject" file was created at: c:\program files\eclipse
help please!
thanks
EDIT: maybe it is worth mentionnig that this is a SVN project. maybe it has something to do with that
What you want is not possible because there might not be a .java file around (only a .class file), the .class file might reside inside a (nested) .jar file and the JVM does not know which classpath entry was used to locate the .class file.
That said, I have tried to solve the same problem for a project of mine. The code goes like this:
private static List<Class> getClassesForPackage(String packagename)
throws ClassNotFoundException
{
// This will hold a list of directories matching the pckgname.
// There may be more than one if a package is split over multiple
// jars/paths
List<Class> classes = new ArrayList<Class>();
List<File> directories = new ArrayList<File>();
try {
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
throw new ClassNotFoundException("Can't get class loader.");
}
// Ask for all resources for the path
Enumeration<URL> resources =
classLoader.getResources(packagename.replace('.', '/'));
while (resources.hasMoreElements()) {
URL res = resources.nextElement();
if (res.getProtocol().equalsIgnoreCase("jar")) {
JarURLConnection conn =
(JarURLConnection) res.openConnection();
JarFile jar = conn.getJarFile();
for (JarEntry e : Collections.list(jar.entries())) {
if (e.getName().startsWith(
packagename.replace('.', '/'))
&& e.getName().endsWith(".class")
&& !e.getName().contains("$"))
{
String className =
e.getName().replace("/", ".").substring(
0,
e.getName().length() - 6);
classes.add(Class.forName(className));
}
}
}
else
directories.add(new File(URLDecoder.decode(
res.getPath(),
"UTF-8")));
}
}
catch (NullPointerException x) {
throw new ClassNotFoundException(packagename
+ " does not appear to be "
+ "a valid package (Null pointer exception)");
}
catch (UnsupportedEncodingException encex) {
throw new ClassNotFoundException(packagename
+ " does not appear to be "
+ "a valid package (Unsupported encoding)");
}
catch (IOException ioex) {
throw new ClassNotFoundException(
"IOException was thrown when trying "
+ "to get all resources for " + packagename);
}
List<String> subPackages = new ArrayList<String>();
// For every directory identified capture all the .class files
for (File directory : directories) {
if (directory.exists()) {
// Get the list of the files contained in the package
File[] files = directory.listFiles();
for (File file : files) {
// add .class files to results
String fileName = file.getName();
if (file.isFile() && fileName.endsWith(".class")) {
// removes the .class extension
classes.add(Class.forName(packagename + '.'
+ fileName.substring(0, fileName.length() - 6)));
}
// add directories to subpackages
if (file.isDirectory()) {
subPackages.add(packagename + "." + fileName);
}
}
}
else {
throw new ClassNotFoundException(packagename + " ("
+ directory.getPath()
+ ") does not appear to be a valid package");
}
}
// check all potential subpackages
for (String subPackage : subPackages) {
classes.addAll(getClassesForPackage(subPackage));
}
return classes;
}
To find the directory of the corresponding .java file you need to configure the source directory you are using.
Tested for simple case:
URL resource = this.getClass().getClassLoader().getResource(this.getClass().getName().concat(".class"));
This should get you the .class file. Bear in mind the .java file may not even be on the system.

Categories