With ImageIO.write() API call, I get NullPointerException when I pass a non-existent path like "\\abc\abc.png". I pass the non-existent path purposely to test something but instead of getting FileNotFoundException, I get NPE. Why is that?
ImageIO.write() API is supposed to throw IOException but don't why I get NPE.
I use exception message string to show it in a message box to user but in this case NPE.getLocalizedMessage() returns empty string and hence the popup is empty with just an icon on it.
He is right, though. For example, this code:
public static void main(String[] args) throws IOException {
BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
File out = new File("\\\\ABC\\abc.png");
ImageIO.write(image, "png", out);
}
gives
java.io.FileNotFoundException: \\ABC\abc.png (The network path was not found)
at java.io.RandomAccessFile.open(Native Method)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:233)
at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:69)
at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:55)
at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:419)
at javax.imageio.ImageIO.write(ImageIO.java:1530)
at javaapplication145.JavaApplication145.main(JavaApplication145.java:24)
Exception in thread "main" java.lang.NullPointerException
at javax.imageio.ImageIO.write(ImageIO.java:1538)
at javaapplication145.JavaApplication145.main(JavaApplication145.java:24)
The reason is that FileImageOutputStreamSpi.createOutputStreamInstance swallows the FileNotFoundException and then the NPE comes when ImageIO.write tries to close a stream that didn't open.
Why the exception is suppressed so brutally, I don't know. The code fragment is
try {
return new FileImageOutputStream((File)output);
} catch (Exception e) {
e.printStackTrace();
return null;
}
The only solution is to verify the path before attempting to use ImageIO.
I found out the reason for NPE for issue mentioned in this thread. Peter Hull is absolutely right in saying
public static void main(String[] args) throws IOException { BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); File out = new File("\\\\ABC\\abc.png"); ImageIO.write(image, "png", out); }
This is exactly my code looks like. Thanks Peter for highlighting.
The reason for this issue is that new FileImageOutputStream() throws a FileNotFoundException but some Sun programmer went and caught the exception, printed the stack trace, and returned null. Which is why it's no longer possible to catch the FileNotFoundException - it's already printed. Shortly afterwards, the returned null value causes a NullPointerException, which is what it being thrown from the method I called. When printed the Stack Trace of the exception, I could see FileNotFoundException along with NPE for the reason mentioned above.
-Nayan
Related
I have a strange behaviour in my java code I would like to ask some advice.
In a multithreading application I wrote this code:
scratchDir.resolve(directoryTree).toFile().mkdirs();
For a bug the Object scratchDir is null, I was expecting a stack trace on the logs but there's nothing about the error.
I have checked the code and I never try to catch the NullPointerException.
Here is the complete method code:
#Override
public void write(JsonObject jsonObject) throws FileSystemException {
Path directoryTree = getRelativePath();
scratchDir.resolve(directoryTree).toFile().mkdirs();
String newFileName = getHashFileName(jsonObject);
Path filePath = scratchDir.resolve(directoryTree).resolve(newFileName);
logger.debug("Write new file Json {} to persistent storage dir {}", newFileName, scratchDir);
File outputFile = filePath.toFile();
if (outputFile.exists()) {
throw new FileAlreadyExistsException(filePath.toString());
}
try (FileWriter fileWriter = new FileWriter(outputFile)) {
fileWriter.write(jsonObject.toString());
fileWriter.flush();
} catch (Exception e) {
logger.error(e);
}
}
Why I don't have the exception in my logs?
Why are you doing this?
The proper way to do this is:
Files.createDirectories(scratchDir.resolve(directoryTree));
don't mix old and new API. The old mkdirs() api DEMANDS that you check the return value; if it is false, the operation failed, and you do not get the benefit of an exception to tell you why. This is the primary reason for why there is a new API in the first place.
Are you sure you aren't confused - and that is the actual problem? The line as you have it will happily do absolutely nothing whatsoever (no directories, and no logs or exceptions). The line above will throw if it can't make the directories, so start there.
Then, if that line IS being run and nothing is logged, then you've caught the NPE and discarded it, someplace you didn't paste.
I am using Tess4j for using Tesseract-OCR technology and I have been using the following code:
During testing I wanted to test the catch close so I was feeding wrong information to Tesseract, which should result in TesseractException.
I managed to induce a TesseractException from the createDocuments() method.
Here is the stack trace:
Note that in the exception we can find doOcr()'s line 125, which is within the try-catch clause, but even though console shows a TesseractException being thrown, the code moves onto line 126 returning true.
I use net.sourceforge.tess4j.Tesseract to initiate the OCR proccess, but I tried net.sourceforge.tess4j.Tesseract1 too, which resulted the same red console output that is done by Tess4j, but no TesseractException.
My question is what am I doing wrong? I am just assuming there is an issue with my code, because TesseractExceptionis being thrown, but my code is not catching it.
Look at the source code of Tesseract.java:
#Override
public void createDocuments(String[] filenames, String[] outputbases, List<RenderedFormat> formats) throws TesseractException {
if (filenames.length != outputbases.length) {
throw new RuntimeException("The two arrays must match in length.");
}
init();
setTessVariables();
try {
for (int i = 0; i < filenames.length; i++) {
File workingTiffFile = null;
try {
String filename = filenames[i];
// if PDF, convert to multi-page TIFF
if (filename.toLowerCase().endsWith(".pdf")) {
workingTiffFile = PdfUtilities.convertPdf2Tiff(new File(filename));
filename = workingTiffFile.getPath();
}
TessResultRenderer renderer = createRenderers(outputbases[i], formats);
createDocuments(filename, renderer);
api.TessDeleteResultRenderer(renderer);
} catch (Exception e) {
// skip the problematic image file
logger.error(e.getMessage(), e);
} finally {
if (workingTiffFile != null && workingTiffFile.exists()) {
workingTiffFile.delete();
}
}
}
} finally {
dispose();
}
}
/**
* Creates documents.
*
* #param filename input file
* #param renderer renderer
* #throws TesseractException
*/
private void createDocuments(String filename, TessResultRenderer renderer) throws TesseractException {
api.TessBaseAPISetInputName(handle, filename); //for reading a UNLV zone file
int result = api.TessBaseAPIProcessPages(handle, filename, null, 0, renderer);
if (result == ITessAPI.FALSE) {
throw new TesseractException("Error during processing page.");
}
}
Exception is thrown at line 579. This method is called by a public method above - at line 551. This is inside the try-catch block with logger.error(e.getMessage(), e); in the catch body (line 555).
Now the question is what you really want to achieve?
If you don't want to see this log, you can configure slf4j to not print the log from this library.
If you want to get the actual exception, it is not possible as the library swallows it. I am not familiar with the library, but looking at the code it doesn't seem like there is any nice option - the method that throws the exception is private and is used only in this one place - under the try-catch block. However, the exception is thrown when api.TessBaseAPIProcessPages(...) returns ITessAPI.FALSE and api has a getter. So you could get it, call TessBaseAPIProcessPages(...) method and check for the result. This might be not ideal as you will probably be processing every image twice. Another solution is to fork the source code and modify it yourself. You might also want to contact the author and ask for advice - you could take it further and submit a pull request for them to approve and release.
Add pdf.ttf file to tessdata path (tessdata/pdf.ttf)
pdf.ttf
I am creating a HTML Webpage Generator as part of a college assignment. What I am trying to do is set the header by taking in the users text and saving it to string through the use of a get / set class. However when I try to output the text to file I get an error.
The code I am using to try and output the string is the following
public static void main(String[] args) throws IOException {
try {
File f = new File("C:\\Users\\David\\Desktop\\output.html");
if(!f.exists()) {
f.createNewFile();
}
FileWriter fw = new FileWriter(f);
fw.write(getHeader());
fw.close();
}catch(IOException io) {
Logger.getLogger(webPage.class.getName()).log(Level.SEVERE, null, io);
}
}
The error that Eclipse is giving me is
Exception in thread "main" java.lang.NullPointerException
at java.io.Writer.write(Unknown Source)
at webPage.main(webPage.java:49)
Can anyone help me correct this please?
As JB Nizet's comment mentions, FileWriter.write() will throw an exception if the argument is null.
If you replace your write with fw.write("Hello World"), you will find no NPE.
So you need to figure out why getHeader() is returning null and fix that.
hi i'm working on a project in which i need to make changes to BASE64 string of an image(jpg)...so at first when i didn't made any changes, the ImageReader was properly working and my image was displayed properly..but when i made changes to my BASE64 string the above exception came..i searched a lot and came to know that im==null comes when ByteStream is not jpeg,png,gif..etc..so what if i have a new type of ByteStream...what should i use?? or what ever my BASE64 string is i need to convert that to an image..so how can i do that??
here is my code snippet:this is to convert BASE64 string to an image
public static BufferedImage decodeToImage(String imageString) throws IOException {
BufferedImage image = null;
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
}
catch (Exception e) {
e.printStackTrace();
}
ImageIO.write(image, "jpg", new File("d:/CopyOfTestImage.jpg"));
return image;
}
Have a look at the Javadocs for ImageIO.read:
Returns a BufferedImage as the result of decoding a supplied InputStream with an ImageReader chosen automatically from among those currently registered. The InputStream is wrapped in an ImageInputStream. If no registered ImageReader claims to be able to read the resulting stream, null is returned. [emphasis mine]
The read method can return null, yet you are not checking for this. In fact the method is probably returning null, which is why ImageIO.write throws an exception when you pass null into it.
First things first, you need to check for error conditions and handle them appropriately (including the null return, but also including any exceptions that are thrown, which you currently catch and ignore).
Now if you're getting null back from ImageIO.read, it means the bytes you passed into the read method did not appear to be a valid image in any known format. You need to look in more detail at the modifications you're making to the base64 string, and ensure that what you're doing is valid, and results in a valid image. Alternatively, if you're getting some other exception thrown, then you need to handle that appropriately.
(As a general rule, don't throw away/skip over errors, because then when things go wrong you have no idea why!)
change this line:
ImageIO.write(image, "jpg", new File("d:/CopyOfTestImage.jpg"));
to something like this
image = ImageIO.read(getClass().getResource("/resources/CopyOfTestImage.jpg"));
The following few lines are part of my servlet that give me an error "java.lang.NullPointerException"
ServletContext context = getServletContext();
InputStream kapil= context.getResourceAsStream("Desktop/images.jpg");
//the above line generates the exception
BufferedImage bufferedImage = ImageIO.read(kapil);
You edited your post. Are you sure it's a NullPointerException and not a IllegalArgumentException?
JavaDocs:
ServletContext.getResourceAsStream() will return null if it cannot find the file you are looking for.
ImageIO.read() throws an IllegalArgumentExeception when the parameter is null. The mentioned input is probably the ImageIO input parameter.
I'd guess that indeed the Input file isn't found.
That would match your original posts problem. Try the following:
ServletContext context = getServletContext();
InputStream kapil= context.getResourceAsStream("Desktop/images.jpg");
if (kapil != null){
//the above line generates the exception
BufferedImage bufferedImage = ImageIO.read(kapil);
} else {
// Use a logging framework if you have it.
System.out.println("The input stream is null!");
}