I just made my first I/O based stuff in Java.
I want to check if the content written to a file is properly saved in, or not.
For which i wrote the following code..
import java.io.*;
public class check implements Serializable {
//Make two variables and methods to initialise them
private int height;
private int width;
public void setWidth(int w){
width = w;
}
public void setHeight(int h){
height = h;
}
public static void main(String[] args) {
check obj = new check();
obj.setHeight(20);
obj.setWidth(30);
try{
FileOutputStream fs = new FileOutputStream("foo.txt");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(obj);
os.close();
}
catch(IOException ex){
}
//We set them to null so we can't access the objects on heap.
obj = null;
//Now we read them back from file
try{
ObjectInputStream is = new ObjectInputStream(new FileInputStream("foo.txt"));
check stored = (check) is.readObject();
//Check to see if it worked.
System.out.println("Variable, stored contains.." + stored.getType());
}
catch(IOException ex){
}
}
}
But it produces the following error.
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - unreported exception java.lang.ClassNotFoundException; must be caught or declared to be thrown
at check.Check.main(Check.java:33)
Anyone got any idea to solve the issue?
Take a look at http://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#readObject(). The method lists a couple of exceptions. For every exception listed that is not a sub-class of RuntimeException you need to either catch the exception or declare that the method can throw that exception. You have only done this for IOException. You also need to do this for the other exceptions listed in the documentation. This needs to be done for all methods that throw non-runtime exceptions.
Your IDE is letting you run some code even though you are missing some classes or despite having compilation errors. Fix the compilation errors before you run them.
Your code is uncompilable at the moment. Line 36 fails.
System.out.println("Variable, stored contains.." + stored.getType());
This is because the class check does not contain a method getType(). Maybe You meant something along the lines of getClass().getName()?
Fix this error and try again. Your own error message does not make sense to me - is it generated by an IDE?
PS. Have a look at Java coding conventions regarding the naming of classes, variables and such. :)
Related
I've been looking for a mistake in my code for hours now but I simply can't find it.
I could locate that the mistake is in this part of my code:
public String getType(File file)
{
String type = null;
try
{
type = URLConnection.guessContentTypeFromName(file.getAbsolutePath());
if (type.startsWith("image"))
{
Log.d(logTag, file.getAbsolutePath());
}
}
catch (Exception e){}
return type;
}
This works absolutely fine but when I do the string comparison directly before the return statement I don't get all types which start with "image".
The same thing happens when I don't use the exception handling block.
I've also displayed the integer values of the string and they do equal.
In case it matters: This is an Android project.
Edit:
E.g I get
/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20150906-WA0000.jpg
in both cases whereas I receive
/storage/emulated/0/Profilbilder/18186367897.jpg
only when I use the code above. And no Exception is thrown for this file.
Edit:
I created a new project and it works as expected now. Since my new code is not exactly the same but almost, I can't tell whether it was a logical mistake or the compiler
When file is null or URLConnection throws some exception, type must be null, then there is a nullpointerException on type.startsWith("image")
Motivation:
To aid in remote debugging (Java), it's useful to be able to request remote servers to send over arbitrary objects to my local machine for inspection. However, this means that the remote server must be able to serialize an arbitrary java object that is not known in advance at runtime.
In particular, I would like to be able to serialize even those objects which don't implement Serializable. I stumbled upon JBossSerialization which claimed with that with JBossSerialization...
...You can serialize classes that are not implementing Serializable
Great! And even better, I managed to find the code that supposedly demonstrates how to do this.
Problem
So pinching the code from schabell.org, I wrote a quick test to check that I could serialize and deserialize without problems:
import org.jboss.serial.io.JBossObjectInputStream;
import org.jboss.serial.io.JBossObjectOutputStream;
import java.io.*;
class MyObj { // Test class which doesn't implement Serializable
public int x;
MyObj(int x) {this.x = x;}
}
public class SerializationTest {
public static void main(String[] args) {
MyObj obj = new MyObj(1);
byte[] byteArray = getByteArrayFromObject(obj); // Try to serialize
MyObj result = (MyObj) getObjectFromByteArray(byteArray); // Try to deserialize
System.out.println(result.x);
}
// Code that I pinched from website below (http://www.schabell.org/2009/03/jboss-serialization-simple-example.html):
public static Object getObjectFromByteArray(byte[] bytes) {
Object result = null;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new JBossObjectInputStream(bais);
result = ois.readObject(); // ERROR HERE!!!
ois.close();
} catch (IOException ioEx) {
ioEx.printStackTrace();
} catch (ClassNotFoundException cnfEx) {
cnfEx.printStackTrace();
}
return result;
}
public static byte[] getByteArrayFromObject(Object obj) {
byte[] result = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new JBossObjectOutputStream(baos);
oos.writeObject(obj);
oos.flush();
oos.close();
baos.close();
result = baos.toByteArray();
} catch (IOException ioEx) {
ioEx.printStackTrace();
}
return result;
}
}
Problem is that the test failed. Debugging indicated that I could only serialize, but not deserialize. The call to ois.readObject() on line 26 is the culprit and gives as SerializationException:
org.jboss.serial.exception.SerializationException: Could not create instance of MyObj - MyObj
at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:342)
at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:239)
at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)
at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)
at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)
at org.jboss.serial.io.JBossObjectInputStream.readObjectOverride(JBossObjectInputStream.java:163)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:364)
at SerializationTest.getObjectFromByteArray(SerializationTest.java:44)
at SerializationTest.main(SerializationTest.java:15)
Caused by: java.lang.InstantiationException: MyObj
at java.lang.Class.newInstance(Class.java:359)
at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:334)
... 8 more
Does anyone know what's going wrong here and how I can get round this?
Or indeed if JBossSerialization isn't the right tool for this, what is?
Edit:
As #Dima points out, the SerializationException is caused by a lack of a public default constructor of the MyObj class. However, adding a default constructor to MyObj isn't an option as I'd like to be able to serialize arbitrary objects, including those without a default constructor.
Well, it is actually impossible to do what you want in a way, that would be both safe and universal.
You can take a look at Kryo, as someone suggested in comments as well. It does have a way to instantiate objects without invoking a constructor, but it is off by default and there is a good reason for it.
Consider this for example:
public class CanonicalObject {
public static HashMap<String,CannicalObject> canons = new HahMap<~>();
public String name;
private CanonicalObject(String name) {
this.name = name;
canons.put(name, this);
}
public static synchronized CanonicalObject getCanonicalInstance(String name) {
CanonicalObject co = canon.get(name);
return co == null ? new CanonicalObject(name) : co;
}
}
(This is a "semi-real-life" example, in that there are real uses for this pattern. I am aware of the "memory leak", there are ways to avoid it in real applications, but they are irrelevant to this example, so I am just ignoring that issue for the sake of simplicity).
If you serialize an instance of this object, when you deserialize it on the other end, the whole "canonicalization" part will be skipped, which can cause subtle problems in application, that are really hard to diagnose, such as comparisons like if(canon1 != canon2) fireMissile() resulting in "friendly fire" and, possibly, a WorldWar III.
Note, that the problem here is broader than just a constructor not invoked by deserialization: the canon.put call could very well be put into getCanonicalInstance() instead of the constructor, and that would present the problem even if the constructor was invoked.
This is an illustration of why, as a matter of policy, you should not be serializing objects that are not designed to be serialized. IT can sometimes work, but, when it does not, it results in situations that are really hard to detect, and usually even harder to fix.
I have a piece of code, that throws NullPointerException sometimes. So far not really interesting. But the Exception occurs in a line, that does not reference any object.
try
{
parser.parse(input);/*line 186*/
}
catch(Exception e)
{
//NPE happens in the next line?
throw new SAXException("Error parsing document", e);/*line 190*/
}
Here the Stacktrace
java.lang.NullPointerException
at com.tejoe.MyXMLParser.parse(MyXMLParser.java:190)
at com.tejoe.MyXMLParser.parse(MyXMLParser.java:168)
....
It happened only twice in the last three months and the code run at least a hundred thousand times.
I already decompiled my code, to make sure the line information were correct and yes they are.
Additional Test
There seems to be something special with SAXException. I did the following test:
import org.xml.sax.SAXException;
public class Test
{
public static void main(String[] args) throws Exception
{
new SAXException("Error", new NullPointerException()).printStackTrace();
}
}
I got the following output
java.lang.NullPointerException
at Test.main(Test.java:7)
Caused by: java.lang.NullPointerException
... 1 more
Solution:
SAXException overrides toString method, to return the Name of the cause Exception.
Now I only wonder, that I did not get the caused by output in the production environment (AIX JAVA)
I wrote following code and generated null pointer exception. It came on line 45 as follow,
Exception in thread "main" java.lang.NullPointerException
at inheritance.parent.Child.main(Child.java:45)
import org.xml.sax.SAXException;
public class Child {
public static void main(String[] args) throws SAXException {
try{
Child c1 = null;
c1.i=0;
} catch(Exception e){
throw new SAXException("Error", e); //Line : 45
}
}
}
The error for your code is proper. You need to find which object you are getting null.
Your code must have changed since you made your last release. This will mess up the line numbers, since they are based on the code at the time it was compiled.
It looks like you've removed some code from that file since the release, meaning that the line numbers are larger than they should be.
Replace your line :
throw new SAXException("Error parsing document", e);
with
e.printStackTrace();
you will find the right error line.
At first I was going to make the question solely about the Image class, but I wanted to make it as broadly applicable as possible.
Basically, here's the scenario. I'm making a file for GUI constants, and in this file I'd like to have final variables for each of the Images I'm using. So my fields are declared like this UP_ARROW is:
public static final Image UP_ARROW;
Then I try to load them when the ImageIO API, like so:
static {
UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}
Unfortunately, this isn't valid, compilable code, because it explicitly throws IOException, which I have to deal with. So I modify it and surround it with a try/catch:
static {
try {
UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}
catch(IOException ioe) {
//TODO
}
}
Now I get a different compiler error. This time it says there's a possibility that the field may not have been initialized. Okay, that makes sense. Thank you for pointing that out to me, compiler. That seems like an easy fix:
static {
try {
UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}
catch(IOException ioe) {
UP_ARROW = null;
}
}
Now, no matter what, the UP_ARROW must be populated with either my image or null. I'm prepared to declare victory and move on. But now I get another, unexpected compiler error:
... Foiled again, compiler!
Hence the question: is there any way to get around this, such that I can dynamically load final fields at runtime? Or do I declare defeat and simply make the Images non-final?
Also, an explanation as to why the compiler won't allow this would be helpful as well. As I understand it, based on the code above, the UP_ARROW object could not have been assigned before reaching the catch{} block, because that's what must have thrown the exception. So if the try{} executes successfully, only one assignment takes place. If it does not execute successfully, still only one assignment take place. How is that not valid?
The following should do it:
static {
Image up_arrow = null;
try {
up_arrow = ImageIO.read(new File("img/upArrow.png"));
}
catch(IOException ioe) {
// log the error?
}
UP_ARROW = up_arrow;
}
It might make sense to enclose the final assignment in a finally block .
NPE's answer is good, but I think this one is (based off his and) better:
public enum Arrows {
UP ("img/upArrow.png"),
DOWN ("img/downArrow.png"),
LEFT ("img/leftArrow.png"),
RIGHT ("img/rightArrow.png");
public final Image myImage;
private Arrows(String fileName) {
Image tempImage;
try {
tempImage = ImageIO.read(new File(fileName));
} catch (IOException e) {
tempImage = null;
}
myImage = tempImage;
}
}
This solves your problem and gives you all the advantages of an enum over static final variables.
I'm writing a java Application that can open and edit files. But I want it to give me an error if the layout of the file isnt as it should be.
My file looks like this:
Title
X Y
Name
X times line
If looked into try and catch but that doesnt give me the right solution to give an error like:
"There is no X or Y specified"
or
"There is nog Title in this file"
Whats the option to do this?
Create your own Exception class that extends Exception. This is sometimes called a domain exception, because it's one that only applies to your problem domain.
Here's an example of how you would code it:
public class FileLayoutException extends Exception {
// extending Exception means you can throw it and declare it to be thrown
}
Declare your method to throw it:
public void readFile() throws FileLayoutException {
// some impl
}
Then use it like this when you detect a problem:
throw new FileLayoutException("There is no X or Y specified");
or
throw new FileLayoutException("There is no Title in this file");
Because your error conditions are "file-related", you may consider extending IOException instead of Exception