I have a java client server program that works fine on a half a dozen computere but is causing a NegativeArraySizeException on site.
This is the code
location = message.indexOf("last");
location += 5;
end = message.indexOf('&', location);
int size = end - location; THIS IS THE ERROR LINE
char[] lastC = new char[size];
message.getChars(location, location+size, lastC, 0);
String firstS = new String(firstC);
String lastS = new String(lastC);
message is an xml message I am reading.
location is an integer that points the the location of a character in the message, the first name in this case.
size is the length of the persons name.
As far as I can tell size is being set as a negative number and I don't know why.
Does anyone know how to fix this or a better was of finding the length of the name ?
This is part of the server side.
As far as I can tell size is being set as a negative number and I don't know why.
If the first call to indexOf cannot locate "last" in the message, then location will be set to -1 and then incremented by 5 to give 4.
If the second call to indexOf cannot find a '&' then end will be set to -1, and size will be negative.
Obviously, the input XML is not in the form you expect.
All in all, that code is pretty dodgy. As a minimum you should check the results of both calls to indexOf and take appropriate error reporting / recovery steps if they are -1.
But the real fix is to not attempt to "parse" XML using crufty string bashing. Use an XML parser, preferably with validation against the relevant schema or DTD. If the XML parser rejects the input, report the error back at who / whatever gave you the broken XML.
Does the message contain last at all? If not, location would be negative, and you should stop processing right there. This error might go unnoticed because you add 5 to location after that, which makes it equal to at least 4 even if last is not in the string (thanks SJuan76).
Even if the message contains last, is it guaranteed that it is followed by at least one extra character? If not, adding 5 to location would point outside the string for sure.
Moreover, end may also be negative if there is no & in the string after location. You should handle that somehow (i.e. by setting end to the length of the message in that case).
Also, if message is a string, you can simply extract a substring of it using the substring method, no need for the getChars magic.
A better solution would probably be something like this (I'm assuming that message is something like an URL and you are looking for the part between last> and the next &, based on your comment for one of the other answers):
location = message.indexOf("last>");
if (location >= 0) {
String lastS;
location += 5;
end = message.indexOf('&', location);
if (end == -1) {
// Handle the case when there is no "&" after "last>" in the message
} else {
lastS = message.substring(location, end);
}
} else {
// Handle the case when there is no "last>" in the message
}
The trouble is that end is less than location. The issue is what message are you expecting and which one you are receiving; the rest of the logic works for certain messages. Check from where you get your message String.
Related
just a beginner in java doing a simple reading file processing some data and writing to a file, however whenever I print to a file I get this inconsistent spacing such as shown below. Especially the zeros are throwing me off. Right now I am padding the strings with empty spaces but I am sure there are better suggestions out there to have consistent spacing between strings in a file. Thanks for the help. I have attached a picture of the inconsistent printing, especially the zeros.
In Apache Commons StringUtils library there are convenient methods to set the proper pad - e.g. rightPad seems to be useful in your case - you could make something like
String row = StringUtils.rightPad(firstValue, lengthOfTheLongestValueInColumn1 + definedColumnMargin) + StringUtils.rightPad(secondValue, lengthOfTheLongestValueInColumn2 + definedColumnMargin) // + ... etc
If these lengthOfTheLongestValueInColumn variables would be calculated dynamically then it would work perfectly but you could also just hardcode some reasonable value (if you know that no value will be longer than, let say, 20 it could have value of 20)
I think best option will be to use String format
return String.format("%1$" + length + "s", inputString)
where length is max size of your digit
you can read more here
I have the following problem: I have a String that I read from a MySQL Database (with the JDBC driver) and have to compare it with another String that I receive over TCP with a BufferedReader. When I use String.equals, false is returned even if the Strings are exactly equal, I even printed both Strings to the console to make sure there aren't any typos or null objects. String.compareTo returns a negative number around -100.
I am really confused here and have no concrete idea how to fix that. Maybe it's related to the database's encoding (UTF-8)?
As requested, here is my code snippet:
public TeleportSign getTeleportSign(String target) {
// I used a HashMap, but I switched to an ArrayList in order to be able
// to compare the Strings directly.
//return signs.get(target);
for(TeleportSign s : signsList) {
// I am printing the Strings here. I even put stars to the left
// and the right of the String to make sure there are no
// spaces or new lines. s.getTarget() returns the String from the DB,
// target is the String sent over TCP.
System.out.println("*" + s.getTarget() + "* " +
String.valueOf(s.getTarget().compareTo(target))
+ " *" + target + "*");
if(s.getTarget().compareTo(target) == 0)
return s;
}
return null;
}
And the console output is:
*TDM1* -84 *TDM1*
Thanks in advance!
Captain
So I rebooted the entire system and retried. Everything works now as expected. I can't explain this to myself because I restarted the JVM multiple times and nothing happened, and a system reboot shouldn't affect a Java program like this.
I am sorry for everyone's time I wasted, but I really appreciate your quick help anyways.
EDIT: I use the trim method from String now. This method cuts off any leading null characters to prevent issues like this one. I hope this will be helpful for someone who has the same problem!
Provided a String, my objective is to check if I can make that String a palindrome string even after re-arranging the characters.
For eg: aaabbbb can be made palindrome by changing to : bbaaabb
So what I did try is to compare all the permutations of the string with its reverse, if it exists, print a YES! . And here is the code so far:
private static void permutation(String prefix, String str)
{
temp.setLength(0); //temp is a StringBuilder
int n = str.length();
if((n==0) && (str.charAt(0)==str.charAt(n-1)))
{
temp.append(prefix);
temp.reverse();
if(prefix.equals(temp.toString()))
{
System.out.println("YES");
System.exit(0);
}
}
else
{
for(int i=0;i<n;i++)
permutation(prefix+str.charAt(i),str.substring(0,i)+str.substring(i+1,n));
}
}
Now the problem is, at runtime I get a java.lang.StringIndexOutOfBoundsException at this line: permutation(prefix+str.charAt(i),str.substring(0,i)+str.substring(i+1,n));
What might be possibly causing this?
This line will give you the exception too:
if((n==0) && (str.charAt(0)==str.charAt(n-1)))
If n==0 then the string is empty, and charAt(0) will fail. Not sure what you're testing here.
I'm not going to debug this for you, but I will suggest a process for how to debug this kind of thing yourself.
Identify the problem. All of the detail about the palindromes is irrelevant. The problem is a java.lang.StringIndexOutOfBoundsException when calling one of the methods on the String.
Narrow in on exactly what's failing. There are several method calls in the line that is failing. If it's not obvious which method call is the problem, either single-step through it with a debugger or break that line into several lines, e.g. by creating intermediate variables to hold intermediate state.
Reproduce the problem in a simplified example. Create a new class with a main() method or write a unit test and write code that shows the problem. Remove everything that isn't absolutely essential to show the problem.
Fix your example. Once you've isolated the problem and read the documentation, it will probably be obvious how to fix it. If it's not, and you're still stuck, post the simple example on Stack Overflow and explain what you are expecting and what you're getting.
Fix your code. Apply the same fix to your original code.
String index out of bound exception -This exception is thrown by the methods of the String class, in order to indicate that an index is either negative, or greater than the size of the string itself.
In above code you are calling permutation() method recursively .
Let's say we passed String str="xy" and prefix as "" to permutation() method first time.
As its length is more than 0 it will come to the else block.
In else block we are looping str with its length.
Here length i.e n is 2.
In first loop, i=0. So prefix + str.charAt(i) will give "" + "x" = "x" and str.substring(0,i)+str.substring(i+1,n)
will give str.substring(0,0)+str.substring(0+1,2)=""+"y"="y".
Now again we are passing these values to permutation() method; i.e. permutation("x","y").
So the time when you passed these value in method, at that time instantly string str became "y" and string prefix became "x"
but still you are in loop, and in second loop i=1 and prefix+str.charAt(1) i.e. "x"+"y".charAt(1) will throw exception.
Here you can see string str="y", length is 1 and we are trying to get char at position 1. This is why you got this exception.
I meet a problem in the Processing, and when i convert the value(string) into float, the first value is good, but the rests are all NaN. I could not find a way to solve this. And i print the string value for test. And it is correct, but after i convert it into float. It will be NaN.
ps: the value is from the serial, i connected my Arduino with Proceesing.
following is a part of codes
while(myport.available() > 0)
{
myString = myport.readString(); //read the string from serial
num = float(myString); // convert the string into float
print(num); // print the num(float), but the first
// value is good, rests are all `NaN` .
//print(myString); // print string, all the values are good
print(' ');
if(myString != null)
{
//num = float(myString);
storeData(myString);
//println(myString);
//print(data[i - 1]);
//println(' ');
delay(1000);
}
}
following is the result
conversion finshed:
not convert, only print string value
following is arduino code
sum = sqrt(Xg*Xg + Yg*Yg + Zg * Zg);
sum *= 10;
sum = (map(sum, 0, 1024, 0, 5000)/10.0);
Serial.println(sum);
delay(100);
I think that the problem is not inside Arduino but inside the Processing code.
I was looking a lot and I note that there is an error that can most likely solve your problem.
You used val = myport.readString(); instead of val = myport.readStringUntil('\n'); .
The differences are few, but in your case would be substantial.
Take a look at ReadString function and ReadStringUntil function.
Anyway, it is also suggested by the sparkFun tutorial.
P.S. Of course, in your Arduino code, you have to use (well, like you were doing) Serial.println(sum); instead of Serial.print(sum) because, in the last case, that would not send to processing nothing before a line feed has been sended.
I find my problem is inside the Arduino code, so i changed the way to send the data from Arduino. I used the println() to send the data. And that's the point lead to NaN. I serached on google, and then i tested different ways to change the way to send until i finded this link:http://www.varesano.net/blog/fabio/sending-float-variables-over-serial-without-loss-precision-arduino-and-processing
And thanks fabio's blog, his blog's introudces a good way to solve this problem. If you have the same trouble, maybe you can fixed by this.
can anyone tell me how to read multiple lines and store their value.
eg:file.txt
Probable Cause: The network operator has issued an alter attribute command for
the specified LCONF assign. The old value and the new value are show
Action Taken : The assign value is changed from the old value to the new
value. Receipt of this message does not guarantee that the new attribute
value was accepted by clients who use it. Additional messages may be.
Probable Cause: The network operator has issued an info attribute command for
the specified LCONF assign. The default value being used is displaye
Action Taken : None. Informational use only.
In the above file, Probable Cause and Action Taken are the column of a database table. And after Probable Cause: those are the value to be stored in the database table for probable cause column, same goes with action taken.
So how can i read the multiple lines and store their value? I have to read the value for probable cause until the line comes with Action Taken. I'm using BufferedReader and the readLine() method to read one line at a time. So can anyone tell me how to read directly from probable cause to action taken no matter how many line comes between them.
The simplest way is probably to just keep a List<String> for each value, with loops something like this:
private static final String ACTION_TAKEN_PREFIX = "Action Taken ";
...
String line;
while ((line = reader.readLine()) != null)
{
if (line.startsWith(ACTION_TAKEN_PREFIX))
{
actions.add(line.substring(ACTION_TAKEN_PREFIX))
// Keep reading the rest of the actions
break;
}
causes.add(line);
}
// Now handle the fact that either we've reached the end of the file, or we're
// reading the actions
Once you've got a "Probable Cause" / "Actions Taken" pair, convert the list of strings back to a single string, e.g. joining with "\n", and then insert in the database. (The Joiner class in Guava will make this easier.)
The tricky bit is dealing with anomalies:
What happens if you don't start with a Probable Cause?
What happens if one probable cause is followed by another, or one set of actions is followed by another?
What happens if you reach the end of the file after reading a probably cause but no list of actions?
I don't have the time to write out a complete solution now, but hopefully the above will help to get you going.