So i was making a maven plugin, which main goal would be to generate extra resource inside of the final jar file, but i couldnt find how to actually put the file inside of the jar.
The closest i got was saving the file in the output directory, which doesnt really help my case, and most of the google search results gave me either documentation on how to use "Apache maven resource plugin" or "how to create maven plugins", neither of them having the information i seek =\
Update 1:
Tried saving the file to the target/classes, but the resulting file is empty (no idea why) and isnt copied to the final jar either way
File dir = new File(project.getBuild().getDirectory(),"classes");
if(dir.exists()){
File result = new File(dir,"AzimDP.json");
try {
getLog().info(gson.toJson(toSave));
gson.toJson(toSave, new FileWriter(result));
} catch (Exception e) {
getLog().warn(e);
}
}else{
getLog().warn("Unable to save file since target/classes doesnt exist");
}
Update 2 and working solution:
turns out i forgot to flush and close the FileWriter, and thus the file was empty. After i fixed that, everything works:
File dir = new File(project.getBuild().getDirectory(),"classes");
if(!dir.exists()) {
dir.mkdirs();
}
File result = new File(dir,"AzimDP.json");
try {
FileWriter writer = new FileWriter(result);
gson.toJson(toSave, writer);
writer.flush();
writer.close();
} catch (Exception e) {
getLog().warn(e);
}
In the end, the working solution based off #GyroGearless comment:
Gson gson = new Gson();
File dir = new File(project.getBuild().getDirectory(), "classes");
if(!dir.exists()) {
dir.mkdirs();
}
File result = new File(dir, "AzimDP.json");
try {
FileWriter writer = new FileWriter(result);
gson.toJson(toSave, writer);
writer.flush();
writer.close();
} catch (Exception e) {
getLog().warn(e);
}
where project is MavenProject and toSave is JsonArray.
Used in Maven 3 at LifecyclePhase "generate resources"
Related
I'm using Apache libraries to edit DOCX file and I want user to choose dir where to save his file. It doesnt matter what folder to select it always thows an excetion and says "path (Access denied)", however, if I choose the directory in my code it works perfectly. Here's some of my code:
XWPFDocument doc = null;
try {
doc = new XWPFDocument(new ByteArrayInputStream(byteData));
} catch (IOException e) {
e.printStackTrace();
}
/* editing docx file somehow (a lot of useless code) */
Alert alert = new Alert(Alert.AlertType.INFORMATION);
DirectoryChooser dirChooser = new DirectoryChooser();
dirChooser.setTitle("Choose folder");
Stage stage = (Stage) (((Node) event.getSource()).getScene().getWindow());
File file = dirChooser.showDialog(stage);
if (file != null) {
try {
doc.write(new FileOutputStream(file.getAbsoluteFile()));
alert.setContentText("Saved to folder " + file.getAbsolutePath());
} catch (IOException e) {
alert.setContentText(e.getLocalizedMessage());
}
} else {
try {
doc.write(new FileOutputStream("C://output.docx"));
alert.setContentText("Saved to folder C:\\");
} catch (IOException e) {
alert.setContentText(e.getLocalizedMessage());
}
}
alert.showAndWait();
Please help me to figure out what I'm doing wrong :(
DirectoryChooser returns a File object which is either a directory or a null (if you did not choose one by pressing cancel or exit the dialog). So in order to save your file, you need to also append the file name to the absolute path of the directory you choose. You can do that by :
doc.write(new FileOutputStream(file.getAbsoluteFile()+"\\doc.docx"));
But this is platform dependent cause for windows it’s ‘\’ and for unix it’s ‘/’ so better use File.separator like :
doc.write(new FileOutputStream(file.getAbsoluteFile()+File.separator+"doc.docx"));
You can read more about the above here
Edit: As Fabian mentioned in the comments below you can use the File constructor, passing the folder ( the file you got from them DirectoryChooser ) and the new file name as parameters which makes the code far more readable :
new FileOutputStream(new File(file, "doc.docx"))
I followed Where to put own properties file in an android project created with Android Studio? and I got an InputStream which reads from my .properties file successfully. However, I can't write to that .properties file, as there is no similar method to getBaseContext().getAssets().open ("app.properties") which returns an OutputStream. I have also read Java Properties File appending new values but this didn't seem to help me, my guess is my file name for the file writer is wrong but I also tried "assets\userInfo.properties" which also doesn't work.
My .properties file is in src\main\assets\userInfo.properties
Properties props = new Properties();
InputStream inputStream = null;
try{
inputStream = getBaseContext().getAssets().open("userInfo.properties");
props.load(inputStream);
props.put("name", "smith");
FileOutputStream output = new FileOutputStream("userInfo.properties"); //this line throws error
props.store(output, "This is overwrite file");
String name = props.getProperty("name");
Log.d(TAG, "onCreate: PROPERTIES TEST NAME CHANGE: " + name);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Current code throws this error:
java.io.FileNotFoundException: userInfo.properties (Read-only file system)
You can't write to the assets folder, as it is inside the APK which is read-only.
Use internal or external storage instead
You can't write to the assets folder. If you want to update your properties file, you'll have to put them some place else. If you want the initial version in the assets or raw folder, just copy it to the default files dir when the app is first used, then read from/write to it there.
I am accessing a File inside the resources folder from the main class
File file = new ClassPathResource("remoteUnitsIdsInOldServer.txt").getFile();
and I am getting this error:
java.io.FileNotFoundException: class path resource [remoteUnitsIdsInOldServer.txt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/Users/lopes/Documents/workspace-sts-3.9.0.RELEASE/telefonicaUtils/target/telefonicaUtils-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/remoteUnitsIdsInOldServer.txt
and I even open the jar file and the file remoteUnitsIdsInOldServer.txt is there, inside classes
The simplest solution for me was,
try {
ClassPathResource classPathResource = new ClassPathResource("remoteUnitsIdsInOldServer.txt");
byte[] data = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
String content = new String(data, StandardCharsets.UTF_8);
} catch (Exception ex) {
ex.printStackTrace();
}
It's depends on your requirements..
Case 1:
Considering you need to access text file from resource. You can simply use apache IOUtils and java ClassLoader.
Snippet (note: IOUtils package --> org.apache.commons.io.IOUtils)
String result = "";
ClassLoader classLoader = getClass().getClassLoader();
try {
result = IOUtils.toString(classLoader.getResourceAsStream("fileName"));
} catch (IOException e) {
e.printStackTrace();
}
Classic way:
StringBuilder result = new StringBuilder("");
//Get file from resources folder
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
result.append(line).append("\n");
}
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
Case 2:
Considering you need to access properties from resources such as xml, properties files.
Its too simple, Simply use spring annotation #ImportResource({ "classpath:application-properties.xml", "classpath:context.properties" })
Hope that will be helpful to you.
Typically, a source tree would look like this:
src/
main/
java/
com/
...
resources/
remoteUnitsIdsInOldServer.txt
And, using standard Maven/Gradle functionality, would produce a JAR like this:
<JAR_ROOT>/
com/
...
remoteUnitsIdsInOldServer.txt
Your listed code should work for this situation. However, you mentioned looking in your JAR "inside classes". I wouldn't think there would be a "classes" folder within the JAR.
Good luck.
Quick one. I'm trying to deploy a program, which borks at the following code. I want to read a properties file named, adequately, properties.
Properties props = new Properties();
InputStream is;
// First try - loading from the current directory
try {
File f = new File("properties");
is = new FileInputStream(f);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace(System.err);
is = null;
}
try {
if (is == null) {
// Try loading from classpath
is = getClass().getResourceAsStream("properties");
}
//Load properties from the file (if found), else crash and burn.
props.load(is);
} catch (IOException e) {
e.printStackTrace(System.err);
}
Everything goes well when I run the program through Netbeans.
When I run the JAR by itself, though, I get two exceptions.
java.io.FileNotFoundException: properties (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
.
.
.
Exception in Application start method
Exception in Application stop method
java.lang.reflect.InvocationTargetException
.
.
.
(exception during props.load(is) because is == null)
I'm running the file from the "dist" folder. I've tried placing the properties file inside the folder with the jar, without result. Normally, the properties file is located in the root project folder.
Any ideas?
You read your file as a resource (getResourceAsStream("properties");). So it must be in the classpath. Perhaps in the jar directly or in a directory which you add to the classpath.
A jar is a zip file so you can open it with 7zip for example add your properties file to the jars root level and try it again.
Thanks to the comments, I built an absolute path generator based on the current run directory of the jar. Props to you, guys.
private String relativizer(String file) {
URL url = RobotikosAnomologitos.class.getProtectionDomain().getCodeSource().getLocation();
String urlString = url.toString();
int firstSlash = urlString.indexOf("/");
int targetSlash = urlString.lastIndexOf("/", urlString.length() - 2) + 1;
return urlString.substring(firstSlash, targetSlash) + file;
}
So my new file-reading structure is:
Properties props = new Properties();
InputStream is;
// First try - loading from the current directory
try {
File f = new File("properties");
is = new FileInputStream(f);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace(System.err);
is = null;
}
try {
if (is == null) {
// Try loading from classpath
String pathToProps = relativizer("properties");
is = new FileInputStream(new File(pathToProps));
//is = getClass().getResourceAsStream(pathToProps);
}
//Load properties from the file (if found), else crash and burn.
props.load(is);
} catch (IOException e) {
e.printStackTrace(System.err);
}
// Finally parse the properties.
//code here, bla bla
i need some help with creating file
Im trying in the last hours to work with RandomAccessFile and try to achieve the next logic:
getting a file object
creating a temporary file with similar name (how do i make sure the temp file will be created in same place as the given original one?)
write to this file
replace the original file on the disk with the temporary one (should be in original filename).
I look for a simple code who does that preferring with RandomAccessFile
I just don't how to solve these few steps right..
edited:
Okay so ive attachted this part of code
my problem is that i can't understand what should be the right steps..
the file isn't being created and i don't know how to do that "switch"
File tempFile = null;
String[] fileArray = null;
RandomAccessFile rafTemp = null;
try {
fileArray = FileTools.splitFileNameAndExtension(this.file);
tempFile = File.createTempFile(fileArray[0], "." + fileArray[1],
this.file); // also tried in the 3rd parameter this.file.getParentFile() still not working.
rafTemp = new RandomAccessFile(tempFile, "rw");
rafTemp.writeBytes("temp file content");
tempFile.renameTo(this.file);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
rafTemp.close();
}
try {
// Create temp file.
File temp = File.createTempFile("TempFileName", ".tmp", new File("/"));
// Delete temp file when program exits.
temp.deleteOnExit();
// Write to temp file
BufferedWriter out = new BufferedWriter(new FileWriter(temp));
out.write("Some temp file content");
out.close();
// Original file
File orig = new File("/orig.txt");
// Copy the contents from temp to original file
FileChannel src = new FileInputStream(temp).getChannel();
FileChannel dest = new FileOutputStream(orig).getChannel();
dest.transferFrom(src, 0, src.size());
} catch (IOException e) { // Handle exceptions here}
you can direct overwrite file. or do following
create file in same directory with diff name
delete old file
rename new file