EDIT: I recommend against saving .jasper files to the temp directory and then attempting to load from that location. It's a lot of trouble.
I am attempting to add JasperReport functionality to a Spring web app. The idea is that a pre-compiled .jasper file can be added to the server's Temp folder and filled then exported by the user.
I can successfully read .jrxml from the classpath, compile it into a JasperReport, fill it, and export it within the same method. In trying to separate these tasks, I've run into trouble. Specifically, when attempting to open an input stream from the temp directory.
The following code successfully creates a compiled .jasper file in the temp directory (I have omitted checks against filename for brevity).
Resource res = appContext.getResource("classpath:jasperreports/"
+ filename + ".jrxml");
File f = new File(
org.apache.commons.lang.SystemUtils.getJavaIoTmpDir(), filename
+ ".jasper");
JasperCompileManager.compileReportToStream(res.getInputStream(),
new FileOutputStream(f));
Trying to READ from the temp folder causes a problem. After checking the temp folder for the newly-created .jasper, I call the following code.
Map<String, Object> params = new HashMap<String, Object>();
String resourcePath = org.apache.commons.lang.SystemUtils.getJavaIoTmpDir().getPath().toString();
Resource compiledReport = appContext.getResource(resourcePath + "/" + filename + ".jasper");
//Directly accessing the folder didn't work, either
//Resource compiledReport = appContext.getResource("C:/Users/<MyUsername Here>/AppData/Local/Temp/SimpleEmployeeReport.jasper");
JasperPrint filledReport = JasperFillManager.fillReport(compiledReport.getInputStream(),
params, mds.getConnection());
Which results in an exception thrown at getInputStream:
java.io.FileNotFoundException: Could not open ServletContext resource [/C:/Users/<MyUsername>/AppData/Local/Temp/SimpleEmployeeReport.jasper]
I'd appreciate any light you can shed on this!
Multipart held tmp files that caused new file names. Creating my own temp directory solved the issue. On Linux the getProperty is missing the trailing slash
String tempDirectory = System.getProperty("java.io.tmpdir");
if( !tempDirectory .endsWith("/") && !tempDirectory .endsWith( "\\") ) {
tempDirectory = tempDirectory +"/";
Related
I get the error "java.io.FileNotFoundException: AuthKey_7RHM5B8NS7.p8 (No such file or directory)", the file is clearly in my directory and I am using the relative path for the file. Here is my projects directory.
Project directory Image
final ApnsClient apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File("AuthKey_7RHM5B8NS7.p8"),
"GL87ZNESF6", "7RHM5B8NS7"))
.build();
As you are trying to fetch file from resource folder hence you need to specify path for that.
File file = new File(getClass().getResource("/AuthKey_7RHM5B8NS7.p8").getFile());
or to get the URL
URL res = getClass().getClassLoader().getResource("AuthKey_7RHM5B8NS7.p8");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();
You should not use the ApnsSigningKey.loadFromPkcs8File method but instead use the loadFromInputStream method.
The reason is that you are using a resource - and if you build a JAR file from your code, as is often done, your resource will be inside the JAR file and you will not be able to get a File object that points to it.
Code:
InputStream in = getClass().getResourceAsStream("/AuthKey_7RHM5B8NS7.p8");
final ApnsClient apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setSigningKey(ApnsSigningKey.loadFromInputStream(in, "GL87ZNESF6", "7RHM5B8NS7"))
.build();
in.close();
I am trying to export zip files to a directory and running into an IOException stating that the file path cannot be found. I am aware that this means that the parent directory does not exist usually, however debugging the line where the file is being written file.getParentFile().exists() returns true, so this is not my issue. To further complicate matters, this only occurs for approximately half of the files written. It is always the same files that fail when unzipping via java, but unzipping them via windows always successfully works.
Here is the code I am using:
ZipInputStream zis =
new ZipInputStream(new ByteArrayInputStream(zipFile));
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
if(!newFile.isDirectory()) {
newFile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(newFile); //Exception occurs here
//newFile.getParentFile().exists() returns true
//copying the path for newFile.getParentFile() into my file browser leads me to a valid, existing folder
//I have tried newFile.createNewFile() and that errors with a similar exception
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
results.add(new Foo());
}
ze = zis.getNextEntry();
}
Example exception:
java.io.FileNotFoundException: \\foo\foo\foo\foo\foo\foo\foo.pdf (The system cannot find the path specified)
Some more notes about the system: the file system is a remote network drive, the system is running windows, and the account has full write access to the drive. I have also verified that naming a file foo.pdf (copy and pasting the name of the file intended to be written) does not cause any issue either.
The issue is that zip files can have trailing spaces in their paths. For example, "Test whatever .zip" could be the file name so java sees the folder as "/Test whatever /" and it tries to create that folder. Windows tells java that it succeeded, but really it created a folder at "/Test Whatever/". When dealing with folders, the file IO has no issue with this, but when writing files, it completely bombs as it's looking for the path explicitly. It does not truncate the extra white space the same way it does when dealing with folders, as you would expect.
Here is the code I used to resolve it:
String path = (outputFolder + File.separator + fileName).replace(" ", "");
File newFile = new File(path);
I am reading properties file to get a file path as below.
String result = "";
InputStream inputStream = null;
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = GetPropertyValues.class.getClassLoader().getResourceAsStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
The properties file has the path specified like below.
configSettingsFilePath = C:\\\\ConfigSetting.xml
Now I get this below exception when I run my code saying file is not found.
Creating instance of bean 'configSettingHelper'
configSettingsFilePath = C:\ConfigSetting.xml
2017-09-18 14:47:00 DEBUG ConfigSettingHelper:42 - ConfigSettingHelper :: ConfigSetting File:configSettingsFilePath = C:\ConfigSetting.xml
javax.xml.bind.UnmarshalException
- with linked exception:
[java.io.FileNotFoundException: C:\Java\eclipse\eclipse\configSettingsFilePath = C:\ConfigSetting.xml (The filename, directory name, or volume label syntax is incorrect)]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:246)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
Instead of reading the path from properties file, if I directly use "C:\ConfigSetting.xml" in the code, it reads the file.
Can you please suggest what I should use in the properties file to specify the path?
Reading the file only fails when the .jar is running.
Running the app from within Netbeans is fine. (Different path)
Also, the path is coming from
URL resourceURL = MyClass.class.getResource("mydir/myfile.txt");
Printing out the path is perfect.
Also, a mypicture.gif in the very same directory loads fine:
ImageIcon mypicture = new ImageIcon(imageURL, description)).getImage();
even when running the .jar. IE: the actual path must be fine.
It is only a text file I try reading via
InputStream input = new FileInputStream(fileName);
is when it fails - and only if it is in the jar.
This is probably because C:\ is not on the classpath. You're using getClassLoader() which presumably returns a ClassLoader.
According to the docs for ClassLoader#getResource:
This method will first search the parent class loader for the
resource; if the parent is null the path of the class loader built-in
to the virtual machine is searched. That failing, this method will
invoke findResource(String) to find the resource.
That file is in the root of the drive, which is not going to be on the classpath or the path of the class loader built-in to the VM. If those fail, findResource is the fallback. It's unknown where findResource looks without seeing the implementation, but it doesn't appear to pay attention to the C:.
The solution is to move the properties file into your classpath. Typically, you'd put property files like this in the src/main/resources folder.
I have a HashSet of Strings, which are names of files that I want to copy from the working direcorory to the "path" directory. I find that the following piece of code should be working, however, I get a java.nio.file.NoSuchFileException: /commits/1/hello.txt exception.
Hashset<String> stagedQueue = HashSet<String>();
stagedQueue.put("hello.txt");
stagedQueue.put("bye.txt");
String path = "/commits/" + commitID;
for (String file : stagedQueue) {
Files.copy((new File(file).toPath()),
(new File(path + "/" + file).toPath()));
What can I do to fix this? I can't figure out why I am getting these exceptions. Please note that I am moving these into an empty directory.
Don't go through File; you use java.nio.file.
Your problem here is that you try and copy your initial file into a directory which does not exist yet:
String path = "/commits/" + commitID;
First of all, this is the destination directory, so call it dstdir, for instance. Then create the base directory and copy the files into it:
final Path basedir = Paths.get("/commits", commitId);
Files.createDirectories(basedir);
for (final String file: baseQueue)
Files.copy(Paths.get(file), basedir.resolve(file));
Fixed: Instead of calling isFile() I used exists() and it seems to be working fine. If possible could someone explain why this change worked?
I'm attempting to write out to an excel file but am having a problem when trying to create that file if the name already exists.
Basically I am taking a file that is uploaded to a server, reading it, and then outputting a report file in a new location with the same filename. I tried to do this by simply checking if the file already existed and then adding a number onto the filename. My code works if the file doesn't exist or if it exists without a number (e.g. filename.xls). If a file exists with the name "filename1.xls" the server just seems to hang when trying to write the file. What can do to fix this?
Here is my code:
String destination = "c:/apache-tomcat-7.0.8/webapps/reports/" + fileName.substring( fileName.lastIndexOf("\\")+1, fileName.lastIndexOf(".")) + ".xls";
int filenum = 1;
while (new File(destination).isFile()) {
destination = "c:/apache-tomcat-7.0.8/webapps/reports/" + fileName.substring( fileName.lastIndexOf("\\")+1, fileName.lastIndexOf(".")) + filenum + ".xls";
filenum++;
}
WritableWorkbook workbook = Workbook.createWorkbook(new File(destination));
That will happen if some process is still keeping the file open. E.g. you've created a FileInputStream on the file to read it, but are never calling close() on it after reading.
Unrelated to the problem, the expanded WAR folder is not the best place to use as a permanent storage. All those files in the expanded WAR folder will get lost whenever you redeploy the WAR. Also hardcoding a servletcontainer-specific path in the code makes it totally unportable.
If your actual intent is to return the Excel file on a per-request basis to the client using a servlet, then you should be using
WritableWorkbook workBook = Workbook.createWorkbook(response.getOutputStream());
// ...
This way it writes to the response immediately without the need for an intermediate file.
Use the File.createTempFile(prefix, suffix, directory) API:
String localName = new File(fileName).getName();
String nameNoExt = localName.substring(0, fileName.lastIndexOf("."));
String extension = localName.substring(fileName.lastIndexOf(".")); // need to include the .
File directory = new File("c:/apache-tomcat-7.0.8/webapps/reports/");
File destFile = File.createTempFile(nameNoExt, extension, directory)