This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I'm confused with the objects and constructor in Java. I query from a SQLiteDatabase but I couldn't get the correct object/answer. I know my codes look messy and I need to clean it up but I don't know where to start...
public static class QObject {
public String word;
public String definition;
public QObject(String word, String definition) {
this.word = word;
this.definition = definition;
}
public QObject getAnswer(String message) {
QObject quizObject = null;
String query = "select * from " + TABLE_NAME + " where " + COL_WORD + " = '" + message + "'";
Cursor cursor = this.getDbConnection().rawQuery(query, null);
if(cursor.moveToFirst()) {
do {
String myword = cursor.getString(cursor.getColumnIndexOrThrow(COL_WORD));
String mydefinition = cursor.getString(cursor.getColumnIndexOrThrow(COL_DEFINITION));
quizObject = new QObject(word, definition);
} while (cursor.moveToNext());
}
cursor.close();
return quizObject;
}
private SQLiteDatabase getDbConnection() {
return dbHelper.getReadableDatabase();
}
}
}
public void searchName(View view) {
String word = null;
String definition = null;
DatabaseTable db = new DatabaseTable(this);
DatabaseBackend dbBackend = new DatabaseBackend(MainActivity.this);
DatabaseObject dbo = new DatabaseObject(this);
DatabaseB.QObject quizobject = new DatabaseB.QObject(word, definition);
DatabaseB.QObject allQuizQuestions = quizobject.getAnswer(message);
String answer = allQuizQuestions.definition;
TextView textView = findViewById(R.id.textView2);
textView.setText(answer);
}
The error message is null object reference:
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
...
Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.justkitting.orion.databasetest.MainActivity$DatabaseB$QObject.definition' on a null object reference
at com.justkitting.orion.databasetest.MainActivity.searchName(MainActivity.java:139)
at java.lang.reflect.Method.invoke(Native Method)
...
Many many thanks.
Your exception is thrown at this line: String answer = allQuizQuestions.definition; and it means that allQuizQuestions is null. So in the line above (DatabaseB.QObject allQuizQuestions = quizobject.getAnswer(message);) you get null from getAnswer(message) method. And this can happen if cursor.moveToFirst() returns false and you never call this line of code: quizObject = new QObject(word, definition);.
One more thing I found: constructor in this line quizObject = new QObject(word, definition); is not using Strings you found in your DB, but values of word and definition from QObject class, which are null at this point. You should use myword and mydefinition instead.
Can you post the code with the line numbers(If you are on eclipse right click on the far left side of the editor and select 'show line numbers' ). it looks like you are calling a method on an object which is null. You night need to do a null check before method invocation
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
my problem is easy normally but i just don't see where is the problem.
-i am declaring an array of a class as a global variable that i reuse in multiple functions inside this other class.
the class instantiated is:
public class Service {
int numticketsin;
String name="mi";
int[] perhour={0,0,0,0,0,0,0,0,0,0};
int moyenneticketperday;
int[] moyenneticketperdayperhour={0,0,0,0,0,0,0,0,0,0};
public Service(){}
}
global var:
Service[] services=new Service[10];
the function where i use try to fill the array:
public void getnamesofservices(){
int x=0;
Connection conn=db.java_db();
try {
Statement stmt = conn.createStatement();
String qry = "SELECT service_name from service ";
ResultSet rs = stmt.executeQuery(qry);
int i=0;
while (rs.next()) {
String namee=rs.getString("service_name");
System.out.println(namee);
services[i].name = namee;
i++;
}
conn.close();
}
catch (SQLException ex)
{
System.err.println("SQLException: " + ex);
}
}
the error:
''' Exception in thread "main" java.lang.NullPointerException: Cannot assign field "name" because "this.services[i]" is null
at com.mycompany.stats.NewJFrame.getnamesofservices(NewJFrame.java:195)
at com.mycompany.stats.NewJFrame.<init>(NewJFrame.java:122)
at com.mycompany.stats.Main.main(Main.java:16)'''
thank you in advance!!
Service[] services=new Service[10];
This means you created and array with 10 positions, but all those positions are empty (meaning they have null inside each and every position of the array).
So, when trying services[i].name you get the NullPointerException because services[i] is null.
There are plenty of ways to do the initialization, that depends on your business cases. But just to name two possibilities:
Initialize it at the declaration:
Service services[] = new Service[] {
new Service(),new Service(), new Service(), new Service(),new Service(),
new Service(),new Service(), new Service(), new Service(),new Service()
};
Or just before using it, in case you are not overriding it:
services[i] = new Service();
services[i].name = namee;
I am getting this error:NumberFormatException: null when I am trying to add score/points to my app.
I created separated table for this because I need multiple tables .
I have no clue what the problem is so thanks to you all.
if(count==4) {
my_db=new DBHelper(this);
sqdb = my_db.getWritableDatabase();
Cursor c_oldPoints= sqdb.query(DBHelper.TABLE_NAME2,null,DBHelper.NICKNAME+"=?",new String[]{Username},null,null,null);
int col_Points=c_oldPoints.getColumnIndex(DBHelper.POINTS);
c_oldPoints.moveToFirst();
while (!c_oldPoints.isAfterLast())
{
OldPoints=c_oldPoints.getString(col_Points);
c_oldPoints.moveToNext();
}
sqdb.close();
int OldP = Integer.parseInt(OldPoints);
OldP+=countPoints;
String SoldP = Integer.toString(OldP);
my_db=new DBHelper(this);
sqdb = my_db.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(my_db.POINTS,SoldP);
Cursor c = sqdb.query(DBHelper.TABLE_NAME2,null,DBHelper.NICKNAME+"=?",new String[]{Username},null,null,null);
c.moveToFirst();
while (!c.isAfterLast())
{
sqdb.update(DBHelper.TABLE_NAME2,cv, DBHelper.POINTS+"=?",new String[]{OldPoints});
c.moveToNext();
}
sqdb.close();
countPoints=0;
}
This is the logcat :-
2019-05-15 18:18:14.101 8513-8513/com.example.user.soundsequ E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.soundsequ, PID: 8513
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:483)
at java.lang.Integer.parseInt(Integer.java:556)
at com.example.user.soundsequ.Game.onClick(Game.java:353)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
The error appears to be in this line
int OldP = Integer.parseInt(OldPoints);
The error is saying that the value of OldPoints is not a string that can be converted to an integer e.g. if it were A or null;
As such either a value extracted from the POINTS column is not a numeric or the value of Username does not match the column NICKNAME in a row. In which case OldPoints will be whatever value it has been set to before the loop.
As the data itself is not available you need to ascertain which of the two situations is causing the issue.
I'd suggest adding some Logging in to determine which.
e.g. by using something like :-
OldPoints = "my debugging value";
Log.d("MYDEBUGGING","OldPoints, before doing anything is " + OldPoints);
Cursor c_oldPoints= sqdb.query(DBHelper.TABLE_NAME2,null,DBHelper.NICKNAME+"=?",new String[]{Username},null,null,null);
int col_Points=c_oldPoints.getColumnIndex(DBHelper.POINTS);
c_oldPoints.moveToFirst();
while (!c_oldPoints.isAfterLast())
{
OldPoints=c_oldPoints.getString(col_Points);
c_oldPoints.moveToNext();
Log.d("MYDEBUGGING","Extracted the value " + OldPoints + " from position + String.valueOf(c_oldPoints.getPosition());
}
sqdb.close();
Log.d("MYDEBUGGING","Trying to convert the value " + OldPoints + " to an integer");
int OldP = Integer.parseInt(OldPoints);
You could also not make the above changes and add a breakpoint (on the line initially indicated) and then use Run/Debug App and inspect the variables (or use multiple breakpoints at suitable places). You may find this useful in regard to debugging Debug your app.
The following code protects against the exception and also protects against an attempt being made to update a non-existent user :-
if (count == 4) {
SQLiteDatabase sqdb = my_db.getWritableDatabase();
Cursor c_oldPoints= sqdb.query(
DBHelper.TABLE_NAME2,null,
DBHelper.NICKNAME+"=?",
new String[]{Username},
null,null,null
);
int col_Points=c_oldPoints.getColumnIndex(DBHelper.POINTS);
if (c_oldPoints.moveToFirst()) {
Oldpoints = c_oldPoints.getString(col_Points);
//Oldpoints = "oops";
int OldP = 0;
boolean can_convert_to_int = true;
try {
OldP = Integer.parseInt(Oldpoints) + countPoints;
can_convert_to_int = true;
} catch (NumberFormatException e) {
e.printStackTrace(); //TODO not necessary probably remove. just for checking the log
}
if (can_convert_to_int) {
ContentValues cv = new ContentValues();
cv.put(DBHelper.POINTS,OldP);
sqdb.update(DBHelper.TABLE_NAME2,cv, DBHelper.NICKNAME + "=?", new String[]{Username});
}
} else {
Log.d("NICKNAMENOTFOUND","No row was found when attemtping to get the old score for User " + Username);
}
}
However
I would suggest that you add a couple of methods to your DBHelper class, these being :-
public int increasePoints(String user, int points_to_add) {
SQLiteDatabase db = this.getWritableDatabase();
SQLiteStatement sql = db.compileStatement(
"UPDATE " + TABLE_NAME2 +
" SET " + POINTS + "=" + POINTS + " +? " +
"WHERE "+ NICKNAME + "=?"
);
sql.bindLong(1,points_to_add);
sql.bindString(2,user);
return sql.executeUpdateDelete();
}
public int getPoints(String user) {
SQLiteDatabase db = this.getWritableDatabase();
int rv = -1;
String whereclause = NICKNAME + "=?";
String[] whereargs = new String[]{user};
Cursor csr = db.query(TABLE_NAME2,new String[]{POINTS},whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
rv = csr.getInt(csr.getColumnIndex(POINTS));
}
csr.close();
return rv;
}
The first method increasePoints performs the change to the points via an UPDATE sql statement and does away for the need to convert the points extracted as a string to an integer. It returns the number of rows that have been updated (1 if the NICKNAME column is always a unique value, 0 if nothing was updated).
The second method getPoints does as it says, it gets the points for the given user, if the user doesn't exist it will return -1.
Your code could then be :-
if (count == 4) {
boolean updated = false; //TODO remove when happy
int old_points = my_db.getPoints(Username); //TODO remove when happy
if (my_db.increasePoints(Username,countPoints) > 0) {
updated = true;
}
int new_points = my_db.getPoints(Username); //TODO remove when happy
//TODO remove following code when happy
String result = "The result of the attempt to update the points for user " + Username;
if (updated) {
result = result + " was successful. ";
} else {
result = result + " was unsuccessful.";
}
Log.d("POINTSINCREASE",result +
" Points were " + String.valueOf(old_points) + " points are now " + String.valueOf(new_points));
}
Note where //TODO remove when happy is coded the lines are just for testing, so the above could be :-
if (count == 4) {
my_db.increasePoints(Username,countPoints);
}
So as of right now I'm trying to retrieve a table from MongoDB which contains only 1 value at the moment. So whenever I try to pull that data from Mongo and insert it into an ArrayList or comparator hashmap that contains an ArrayList it outputs a null pointer for some odd reason. I'm not exactly sure why it's throwing a null pointer when the table isn't even null itself.
Error
Caused by: java.lang.NullPointerException
at krimsonlib.account.Account.addMultiplier(Account.java:538) ~[?:?]
at krimsonlib.account.AccountManager.MongoTOMap(AccountManager.java:169) ~[?:?]
at krimsonlib.account.AccountManager.makeProfile(AccountManager.java:61) ~[?:?]
at krimsonlib.core.join(core.java:37) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_66]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_66]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.8.7-
... 14 more
This is the comparator method to add a list to an existing list.
Line 538
List<String> multipliers;
//comparator
public Account(String id, String uuid, String name, String kingdom, String rank, String recruit, String joinDate, String lastOnline, List<String> multipliers, List<String> friends,int favor, int playtime, int crystals, int coins, int networklevel, int networkexp, List<String> achievements, List<String> pets, List<String> gadgets, List<String> particles, List<String> cloaking, List<String> clothing){
this.id = id;
this.uuid = uuid;
this.name = name;
this.kingdom = kingdom;
this.rank = rank;
this.recruit = recruit;
this.joinDate = joinDate;
this.lastOnline = lastOnline;
this.multipliers = multipliers;
this.friends = friends;
this.favor = favor;
this.playTime = playtime;
this.crystals = crystals;
this.coins = coins;
this.networklevel = networklevel;
this.networkexp = networkexp;
this.achievements = achievements;
this.pets = pets;
this.gadgets = gadgets;
this.particles = particles;
this.cloaking = cloaking;
this.clothing = clothing;
}
public void newAccount(){
UtilMap.account.put(uuid, new Account(getID(), getUUID(), getName(), getKingdom(), getRank(), getRecruit(), getJoinDate(), getLastOnline(), getMultipliers(), getFriends(), getFavor(), getPlayTime(), getCrystals(), getCoins(), getLevel(), getExp(), getAchievements(), getPets(), getGadgets(), getParticles(), getCloaking(), getClothing()));
}
public void addMultiplier(List<String> multipliers) {
this.multipliers.addAll(multipliers); // this is line 538
}
This method pulls all the data from that specific user and inserts it into an comparator
MongoToMap method
public static void MongoTOMap(UUID uuid){
String trim = uuid.toString().replace("-", "");
String nontrim = uuid.toString();
Account ac = new Account();
DBObject r = new BasicDBObject("uuid", nontrim);
DBObject found = Mongo.users.findOne(r);
if ( found != null ){
ac.setID((String) found.get("_id"));
ac.setUUID((String) found.get("trimuuid"));
ac.setName((String) found.get("name"));
ac.setKingdom((String) found.get("Kingdom"));
ac.setRecruit((String) found.get("recruit"));
ac.setCrystals((int) found.get("crystals"));
ac.setCoins((int) found.get("coins"));
ac.setRank((String) found.get("rank"));
ac.setFavor((int) found.get("favor"));
ac.setJoinDate((String) found.get("First_Join_Date"));
ac.setLastOnline((String) found.get("Last_Join_Date"));
ac.addPlayTime((int) found.get("Playtime"));
ac.setLevel((int) found.get("Network_Level"));
ac.setExp((int) found.get("Network_Exp"));
ac.addMultiplier((List) found.get("Multipliers"));
ac.addFriend((List) found.get("friends"));
ac.addAchievement((List) found.get("achievements"));
ac.addPet((List) found.get("pets"));
ac.addGadget((List) found.get("gadgets"));
ac.addParticle((List) found.get("particles"));
ac.addCloak((List) found.get("cloaking"));
ac.addClothes((List) found.get("clothing"));
ac.newAccount();
System.out.println("[Mongo]- Converted user `" + UtilMap.account.get(trim).getName() + "` data to Map, Method/MongoTOMap #" + UtilMath.genReceipt());
} else {
//this error should NEVER occur
}
}
You might need to use the "long" constructor of Account:
if (found != null) {
Account ac = new Account(
(String) found.get("_id"),
(String) found.get("trimuuid"),
... ,
(List) found.get("Multipliers"),
...
);
ac.newAccount();
}
OR change Account:
public void addMultiplier(List<String> multipliers) {
if (this.multipliers != null) {
this.multipliers.addAll(multipliers);
} else {
this.multipliers = multipliers;
}
}
You are declaring the variable multipliers, but you never initialize it.
In that case the variable has a null value except you pass a valid List<String> to your Account constructor, but your code only uses the default constructor (new Account()), so the list stays null.
If your multipliers is a valid list, the only reason for a NullPointerException in your given line is, that you pass an invalid (null) list to addMultiplier.
To find out the reason for the exception you can either debug your application or add a logging like that:
public void addMultiplier(List<String> multipliers) {
if(this.multipliers == null)
{
System.out.println("this.multipliers is not set correctly");
}
if(multipliers == null)
{
System.out.println("parameter multipliers is not set correctly");
}
this.multipliers.addAll(multipliers);
}
EDIT: Oh, I was too slow :)
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
My app craches when i try to update my database it gives me the following problem
attempt to invoke virtual method 'android.database.cursor com.leoni.bd.Gestion_db.FindDate(java.lang.String)' on a null object reference
i couldn't find the null object i tried many things but it didn't work ! i need help please !
this is my Gestion_db.java class
private SQLiteDatabase _myDbm;
public Gestion_db(Context pContext) {
SqliteCreator s = new SqliteCreator(pContext, Stat.DB_NAME, null, 1);
_myDbm = s.getWritableDatabase();
}
public void close() {
_myDbm.close();
}
public Cursor FindDate(String Attribute) {
String query = "SELECT * FROM " +Stat.TABLE_NAME +" WHERE ? LIKE '%?%' ";
return _myDbm.rawQuery(query, new String[] {Stat.COL_DATE,Attribute});
}
this is the method from my Controle.java activity wich contain the cursor
//header of the activity
private Gestion_db _myGestionDB;
private String _myRecognizedText = null;
// Mise à jour de la base de données quelque soit l'action
private void MiseAJour() {
String dateCourante = new SimpleDateFormat("yyyy:MM:dd",Locale.getDefault()).format(new Date());
Boolean existe=false;
Cursor c = _myGestionDB.FindDate(dateCourante);
if (c.getCount() != 0) {
c.moveToFirst();
while (!c.isAfterLast()) {
String ldate = c.getString(c.getColumnIndex(Stat.COL_DATE));
String lMatricule = c.getString(c.getColumnIndex(Stat.COL_TEXTE_OCR));
if (ldate.equals(dateCourante)&& lMatricule.equals(_myRecognizedText)) {
existe=true;
break;
}
c.moveToNext();
}
}
if (existe){
UpdateHeure(_myHeure);
}else{
AddVoyage();
}
}
this ic Stat.java class wich contains some Strings
public class Stat {
public static final String DB_NAME = "leoni.db";
public static final String URL_CHECK = "http://192.168.1.6/check.php";
public static final String GET_URL = "http://192.168.1.6/getChauffeurs.php";
public static final String COL_ID = "_id";
// Gestion des déplacements
public static final String TABLE_NAME = "gestion_des_deplacements";
public static final String COL_TEXTE_OCR = "texte_ocr";
public static final String COL_DATE = "date";
public static final String COL_HEURE_DEPART = "heure_depart";
public static final String COL_HEURE_ARRIVEE = "heure_arrive";
public static final String CREATE_TABLE_DEPLACEMENTS = "CREATE TABLE "
+ Stat.TABLE_NAME + " (" + Stat.COL_ID
+ " INTEGER PRIMARY KEY autoincrement," + Stat.COL_TEXTE_OCR
+ " VARCHAR(40)" + "," + Stat.COL_CHAUFFEUR + " VARCHAR(50)" + ","
+ Stat.COL_DATE + " VARCHAR(50)" + "," + Stat.COL_HEURE_DEPART
+ " VARCHAR(30)" + "," + Stat.COL_HEURE_ARRIVEE + " VARCHAR(30));";
// Gestion des chauffeurs
public static final String COL_MATRICULE = "matricule";
public static final String COL_CHAUFFEUR = "chauffeur";
}
Your stacktrace gives you all the needed information:
com.leoni.bd.Gestion_db.FindDate(java.lang.String)' on a null object reference
What is says is that object of type Gestion_db is null. So you look in your code for this object, and you have only one instance of it _myGestionDB, as noted by #ρяσѕρєя.
The error message identifies the method that is the subject of the problematic invocation as com.leoni.bd.Gestion_db.FindDate(java.lang.String). It follows, therefore, that the type of the expression on which the invocation is performed must be com.leoni.bd.Gestion_db or one of its subtypes.
The only candidate in the code you posted is instance variable _myGestionDB. The code you posted does not give any particular reason to think the value would be non-null. Instance variables of reference type are initialized to null by default if they have no initializer. If you fail to set its value to something else prior to invoking the method you show, then it will still be null when the method invocation attempt occurs.
I need to know if there is a way to say that int type is not found in Java Android.
I'm writing an android application,which is actually written first for Iphone, and have a little issue. At some point I have to check if the int type which returns a method is not found and if it's true do some calculations. The problem is that when I did that in Java as if(Id==0) it's throwing me an exception even if the Id is 0.
this is my method :
private static int localUserIdByServerUserId(int serverUserId, String serverName){
dbHelper = new DataBaseHelper(context, "stampii_sys_tpl.sqlite", null, 1);
dbHelper.getDatabase();
String query = "SELECT id FROM users WHERE objectId = "+serverUserId+" AND serverName = '"+serverName+"' LIMIT 1";
ArrayList<String> result = new ArrayList<String>();
cursor = dbHelper.executeSQLQuery(query);
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
result.add(cursor.getString(cursor.getColumnIndex("id")));
cursor.moveToNext();
}
Log.i("result ","Result : "+result.toString());
Log.i("CURSOR ","Cursor Position : "+cursor.getPosition());
int uuid = Integer.parseInt(result.get(cursor.getColumnIndex("objectId")+1));
Log.w("localUSerByIdServerUserId","LocalUserByIdServerUserId result : "+uuid);
cursor.close();
return uuid;
and here is how I'm using it :
int uuId = rpc.lUserIdByServerUserId(userId,newServerName);
Log.w("uuId","uuId : "+uuId);
if(uuId==0){
// do some calculations
}
Any suggestions ?
lUserIdByServerUserId() could throw an exception when the user is not found.
e.g.
try {
int uuId = rpc.lUserIdByServerUserId(userId,newServerName);
Log.w("uuId","uuId : "+uuId);
}
catch (NotFoundException nfe) {
// do some calculations
}
You will need to modify lUserIdByServerUserId() to throw the exception. You may also need to define your own NotFoundException class if a suitable exception doesn't already exist in the Java libraries.
EDIT:
Alternatively, following on from #mthpvg's answer, you could change lUserIdByServerUserId() to return an Integer type, which can be set to null if not found and tested.
e.g.
Integer uuId = rpc.lUserIdByServerUserId(userId,newServerName);
if (uuId == null) {
// Do some calculations
}