the value memanufacturer is retrieved from xml document using jdom and when this value is assigned to meman array it throws NullPointerException.
Element memanufacturer = (Element) row27.get(j9);
meman[0] = memanufacturer.getValue();
what could be the posssible mistake.
Thanks
Assuming the exception by the second line of code, there are two obvious possibilities:
memanufacturer may be null
meman may be null
We can't tell which of these is the case, but you should be able to.
EDIT: Okay, so now we know that meman is null, that's the problem. I would suggest you use a List<String> instead:
List<String> meman = new ArrayList<String>();
...
Element memanufacturer = (Element) row27.get(j9);
meman.add(memanufacturer.getValue());
Using a List<String> instead of an array means you don't need to know the size before you start.
However, the fact that you didn't understand the error suggests you should really read a good introductory Java book before going any further with a real project. You should definitely understand how arrays, collections etc work before dealing with XML and the like. It will save you a lot of time in the long run.
Related
I have JSON like below
{
"a1": "aaa",
"b1": 333,
"c1": {
"c1": "ccc",
"d1": "ddd",
"f1": [
{"a1": "xyz"},
{"b1": "lmn"},
{"c1":123.00}
]
}
}
I am reading the file into String and creating a JSONObject as below
JSONObject json = new JSONObject(new JSONTokener(str));
The JSON is coming to my application from outside so the content can be very different in times. Say it can be completely null or some of the elements can be null or array size can be 0 or 1 or more etc.
When I am working on the JSONObject I can keep on checking all the elements using
json.has and !=null
so that it does not throw any exception.
I can have the code as below
if(
json.has("c")
&& json.getJSONObject("c")!= null
&& json.getJSONObject("c").has("f")
&& json.getJSONObject("c").getJSONArray("f").length() > 1
&&json.getJSONObject("c").getJSONArray("f").getJSONObject(1).has("b")
){
String x = json.getJSONObject("c").getJSONArray("f").getJSONObject(1).getString("b");
}
That makes the code having a long list of if conditions.
However I am thinking instead I can just enclose the statement with try catch
try {
String x = json.getJSONObject("c").getJSONArray("f").getJSONObject(1).getString("b");
}catch(JSONException e) {
//log and proceed
}
Please suggest if there is any valid reason in this case to put a long if conditions rather than just try - catch - log and proceed.
Also can you share if using JSONException has any "pros" in this context ?
Option 0: Long If-Statement
I think this is far too convoluted, especially as the chain gets longer. The only case where I would consider a remotely similar solution is if the user needs to know exactly at which point the problem lies and there are specific guidelines on how to solve this and how this may occur in a very specific use case, however in that case you need a large number of if statements and log statements.
Option 1: Try-Catch
Try-catch, as you suggested, is indeed possible, however you need to make sure that you catch all possible exceptions that can occur when a JSON field is not present or of the wrong type, for example ClassCastException and NullPointerException. It is short but not very elegant and as the other answerer said might hide other exceptions (but you could still log the stack trace).
Option 2: Java 8 Optional
Another option is to find a library that allows you to use the Java 8 Optional type. For example, this is suggested using Jackson. This is more elegant but could become a large chain as well. Also this adds one more dependency to your project.
Option 3: Path Expressions
A third option would be to use path expression JsonPath, where you can put all your statements into one expression and get all results for that. In my opinion this is the perfect use case and by far the best solution. The only downside is that this adds one more dependency to your project.
Thanks to the responses above, below is how the problem has been solved.
JSONPath is working the best for the scenario I mentioned. Thanks to #Konrad.
First create a configuration object of type com.jayway.jsonpath.Configuration
Configuration conf = Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).mappingProvider(new JsonOrgMappingProvider()).jsonProvider(new JsonOrgJsonProvider()).build();
Option.SUPPRESS_EXCEPTIONS - This will help to suppress the exception in case an element is missing
mappingProvider(new JsonOrgMappingProvider()).jsonProvider(new JsonOrgJsonProvider() - This uses the right provider so that when we parse the json we don't need to convert the JSONObject to String thus giving optimal performance.
DocumentContext docContext = JsonPath.using(conf).parse(json);
If we use default provider then we need to parse the JSONObject as follows
DocumentContext docContext = JsonPath.using(conf).parse(json.toString());
Then to read the element I used
docContext.read("$.a.b.c.d.values[0].e.f")
The performance is now optimal as well. The reason it was taking more time and memory was because
I was reading and parsing at the same time in a loop. Later on I moved the parsing out of loop.
I was using default provider and was doing json.toString()
Please suggest if there is any valid reason in this case to put a long if conditions rather than just try - catch - log and proceed.
Here are a couple of reasons:
Efficiency: creating, throwing and catching an exception is relatively expensive. Exactly how expensive is version dependent, and probably context dependent too. In recent versions, the JIT compiler can (AFAIK) optimize some sequences into a conditional branch. However, if you are going to log the exception, then the JVM is going to have to create an exception object and populate the stacktrace, and that this the most expensive part.
If you log NullPointerException for:
json.getJSONObject("c").getJSONArray("f").getJSONObject(1).getString("b")
you may not be able to tell which of the components was missing or null. The line number in the stacktrace won't be sufficient to distinguish the cases. (With a JSONException the exception message will give you more clues.)
You also can't distinguish the case where json is null, which is probably a different kind of problem; i.e. a bug. If you treat that as a data error, you are making it difficult to find and fix the code bug.
If you catch all exceptions (as suggested by another answer), you are potentially hiding more classes of bugs. Bad idea.
Also can you share if using JSONException has any "pros" in this context ?
The only real "pro" is that it is possibly less code, especially if you can put the try ... catch around a lot of this code.
The bottom line is that you need to weigh this up for yourself. And one factor is how likely it is that you will get JSON that doesn't match your code's expectations. That will depend in part on what is producing the JSON.
I set id attribute the following way:
Element node = document.createElement("something");
node.setAttribute("id", "1");
node.setIdAttribute("id", true);
Then I check if this is really id attribute:
node.getAttributeNode("id").isId());
returns true
But when I try to get the node by its id
document.getElementById("1");
or even
document.getElementById(node.getAttributeNode("id").getValue())
I get null
What I'm doing wrong?
Despite the fact that you put the wrong tag, it looks like you defined the ID of your element to be "1" So that means to reference it, you should also reference it by "1"
document.getElementById("1");
would return you the DOM object in your markup, so long as it exists in the markup. Depending on the frameworks, it might be pulled from the Dom, but that is not always the case for beginner programming.
As a note for you, a ID should be unique, but at the same time it is good to name it something human readable. The reason for it is that you will come back to this code later and have absolutely no clue what it does.
If you name things accordingly, it will make it easier on you, also allowing you to create and follow the best practices for programming in general.
Apart from that in the previous answers.
The problem with your code is that the created node
var node = document.createElement("sector");
node.setAttribute("id", "1");
is not in the document yet. You must add it.
Example
// Adding the node to the body.
document.body.append(node)
and now
document.getElementById(1)
How can I tell programmatically if a JAXB element is "empty" ?
<fis:MyRequest/>
Normally, with data, it may look like this:
<fis:MyRequest>
<fis:ABC>X</fis:ABC>
<fis:XYZ>6000</fis:XYZ>
</fis:MyRequest>
But sometimes it can be empty and I want to isolate these cases in code.
In this case it is easy to check
if (myRequest.getAbc() == null && myRequest.getXyz() == null) { ... }
But imagine if there are many more sub-elements, this won't be practical.
I thought about generating the myRequest element to a string, and checking if it was a single tag ending with />but this seems like using an elephant to chase a grasshopper (overkill, in other words).
Is there a handy utility function sitting around some place that does this?
Thanks in advance.
Given that the equals() method has been generated (see note below) you can compare the JAXB element to a new instance of the same element type.
MyRequest EMPTY_MYREQYEST = new MyRequest();
if (myRequest.equals(EMPTY_MYREQUEST)) { ... }
I can't see any disadvantage to this approach (?)
note: The -Xequals and -XhashCode flags are most likely required when generating java code from the xsd
I have an array at actionTable.get(state).
When I go to add an onject to the array, namely the Reduce, the properties of the reduce don't seem to go with it.
The array is of type Action[] where Action is the superclass of Reduce, could this be the reason?
Adding the reduce to the array:
actionTable.get(state)[t] = new Reduce(st.items.get(item).prod);
Checking to see if the field head is defined before adding it:
System.out.println(Prod.prods.get(st.items.get(item).prod).head);
Checking to see if the newly added reduce has the correct head field:
System.out.println(actionTable.get(state)[t].prod.head);
A NullPointerException occurs on the last print statement. The .prod part is defined but the .prod.head is null, even though the original prod object had a defined head.
This is the constructor for Reduce:
Reduce(int pr) {
p = pr;
length = Prod.prods.get(pr).length;
prod = Prod.prods.get(pr);
}
All of the RHS of the assignments in the constructor are defined. So, I don't understand why the head field, within the prod object that the new Reduce has access to is not defined when you access it through the actionTable.
Trust inheritance and all. Most likely with arrays is, that different array instances are involved (if you enlarge/copy array references). Some more System.out.println's will help there.
The first thing you always should do is this: got to your break points view in your IDE, check "stop on Exception thrown" and perhaps give the name NullPointerException.
Then run your code in the debugger and it will stop exactly at the point where the NullPointerException is thrown.
I'm parsing a XML file with Commons Digester and I don't understand what's wrong in my code: I'm stuck with this java.lang.NullPointerException.
THis is the code: http://pastie.org/1708374
and this is the exception: http://pastie.org/1708371
I guess it is a stupid error
thanks
Well, this is the problem:
if (centroids.length == 0)
You're never assigning a value to centroids as far as I can see, so it will always be null. Then when you try to dereference it in the line above, it will throw NullPointerException.
The first that the next line of code tried to use centroids[0] suggests that you don't really understand Java arrays. Perhaps you really wanted a List of some description?
I would also strongly suggest that instead of a Map<String, String> which always has the same five keys, you create a type (e.g. Centroid) which has the properties title, description, tags, time, and event. Then you can just make centroids a List<Centroid>:
List<Centroid> centroids = new ArrayList<Centroid>();
then when you get some data...
Centroid centroid = new Centroid(...);
centroids.add(centroid);
Oh, and you're also currently using == to compare strings... don't do that: use equals, as otherwise you'll be comparing string references.
As a general note on how to read a NPE stacktrace:
When you get an exception stack trace, look at the Caused by line and the first line after it
Caused by: java.lang.NullPointerException
at CentroidGenerator.nextItem2(CentroidGenerator.java:31)
A null pointer exception most often occurs when you try to invoke a method on an object and that object is null.
The error message above tells you that the error occurs on line 31 of CentroidGenerator.java:
if (centroids.length == 0) {
Method invokation is of the format object.method, so you know that in this instance the object that is null is centroids.
A quick visual way to determine what's null is to just look at what's on the left of dots on the line where the exception occurs. In lines where you have multiple method calls, you don't immediately know what object is null and you may need some more exploration, but not in this instance.
To fix the problem, refer to Jon's answer.