classnotfoundexception when deserialize an object? [duplicate] - java

This question already has answers here:
readobject method throws ClassNotFoundException
(2 answers)
Closed 7 years ago.
I am working on windows application in java:
I just test a button that make function login in my system:
My button action performed code:
private void loginActionPerformed(java.awt.event.ActionEvent evt) {
if(emp.isSelected()) // get the selected radio button
{
Account a = new Account();
Emp e = new Emp();
a.setUsername(username.getText().toUpperCase());
a.setPassword(password.getText().toUpperCase());
e.login(a);
this.dispose();
}
else if(supp.isSelected())
{
}
else if(admin.isSelected())
{
Account a = new Account();
Admin m = new Admin();
a.setUsername(username.getText().toUpperCase());
a.setPassword(password.getText().toUpperCase());
m.login(a);
this.dispose();
}
else
JOptionPane.showMessageDialog(null, "Please select a choice", "Alert", JOptionPane.INFORMATION_MESSAGE);
}
The function login code:
public class Emp
{
public void login(Account a)
{
boolean find = false;
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new FileInputStream("C:\\Users\\فاطمة\\Downloads\\employees.bin"));
ArrayList<Account> b = (ArrayList)in.readObject();
Iterator<Account> i = b.iterator();
while(i.hasNext())
{
Account ac = i.next();
if(ac.getUsername().equals(a.getUsername()) && ac.getPassword().equals(a.getPassword()))
{
find = true;
}
else
JOptionPane.showMessageDialog(null, "Wrong username or password .. try again !!", "Login Failed",JOptionPane.ERROR_MESSAGE);
}
if(find)
{
JOptionPane.showMessageDialog(null, "Welcome " + a.getUsername(), "Login Success", JOptionPane.INFORMATION_MESSAGE);
emp_page e = new emp_page();
e.setLocation(350, 150);
e.setSize(400, 490);
e.setTitle("Products Management");
e.setVisible(true);
}
} catch (FileNotFoundException ex) {
//Logger.getLogger(Emp.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException | ClassNotFoundException ex) {
//Logger.getLogger(Emp.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
in.close();
} catch (IOException ex) {
//Logger.getLogger(Emp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
The account class code:
import java.io.Serializable;
public class Account implements Serializable{
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
I have a problem: i receive error:
java.lang.classnotfoundexcetpion:Account
and after searching for error reason i found that serialization is the problem of throwing this error because i test this code before in another function that dont use serialization and its worked perfectly.
so my question is: how to fix this error?
NOTE: my application is not a client-server application ... so there is no two projects created ... just only one.

long discussions about this:
ClassNotFoundException when deserializing a binary class file's contents
ClassNotFoundException during Deserialization of a just-serializaed class
Java SerialIzation: 'ClassNotFoundException' when deserializing an Object
3 advices :
be sure to put the private static final long serialVersionUID = XXX;
be sure to embark your class in your classpath/jar
force it in code with Account ac=new Account(); // See if problem here
it helps ?

Related

Java Return Null When Tried to Get Method

first of all I know this is duplicated question. But I've search and tried from stackoverflow listed on Google to quora but still cant resolve my Get method still return null.
This is my class loginModel.java under package com.hello.model
public class loginModel {
public String username;
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return this.username;
}
}
This is my loginView.java under package com.hello.view
import com.hello.model.loginModel;
public class loginView extends javax.swing.JFrame {
loginModel login = new loginModel();
public loginView() {
initComponents();
this.setLocationRelativeTo(null);
loginFunction();
}
private void loginFunction(){
String username = usernameText.getText();
String password = passwdText.getText();
String query = "select * from access where username = '" +username+ "' AND password = '" +password+"'";
databaseConnect db = new databaseConnect();
try (Connection con = DriverManager.getConnection(db.url, db.user, db.password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(query)) {
if(rs.next()) {
if(username.equals(rs.getString("username")) && password.equals(rs.getString("password"))){
JOptionPane.showMessageDialog(null, "login Success");
String name = rs.getString("name");
String privilege = rs.getString("privilege");
login.setUsername(name);
menu = new menuView();
menu.setVisible(true);
this.setVisible(false);
}
} else {
JOptionPane.showMessageDialog(null, "username or password incorrect");
}
} catch (SQLException e) {
System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}
I want call my username from menuView.java under package com.hello.view after login success
import com.hello.model.loginModel;
import com.hello.view.loginView;
public class menuView extends javax.swing.JFrame {
private String username;
loginModel login = new loginModel();
public menuView() {
initComponents();
this.setLocationRelativeTo(null);
initMenu();
}
private void initMenu(){
username = login.getUsername();
JOptionPane.showMessageDialog(this, username);
}
}
As per my question when I call Get method from loginModel, messagebox return null.
I've tried:
Put system.out.println directly in loginModel.java, value return
and call system.out.println in menuView.java at the same time but value return null. How?
Send string between jframe with menu = menuView(username) in loginView.java and retrieve in menuView.java, value return null
Using no model and create set string in loginView and call it in
menuView, value return null
I need values that I want to use in another class/package/jframe. Am I doing wrong?
I am not well versed in Swing but I can see the problem, just not the exact solution.
Your code creates an instance of loginModel in both the menuView and in loginView. Then in loginView is sets the name in the instance it has, in in menuView it gets the name from its own instance.
You need to create a single instance of the model and share it between the two views.
In a pojo way I would pass the loginModel to both "views" in a constructor.
menu = new menuView(login);
And in menuView
public menuView(loginModel login) {
this.login = login;
}
Your menuView instance isn't using the loginModel class that you instantiate in loginView, it's using the new one you created using new menuView() when you initialized the login variable in the menuView class. You just need to add a setter method for the loginModel attribute in the menuView class like this:
import com.hello.model.loginModel;
import com.hello.view.loginView;
public class menuView extends javax.swing.JFrame {
private String username;
loginModel login = new loginModel();
public menuView() {
initComponents();
this.setLocationRelativeTo(null);
initMenu();
}
private void initMenu(){
username = login.getUsername();
JOptionPane.showMessageDialog(this, username);
}
public void setLogin(loginModel loginModel) {
this.login = loginModel;
}
}
Then call the setter in loginView.loginFunction like this:
... code before
login.setUsername(name);
menu = new menuView();
menu.setLogin(login);
menu.setVisible(true);
this.setVisible(false);
... code after
Notice the only changes to your code are the added setLogin method on the menuView class and the call to menu.setLogin(login) in loginView.loginFunction.
You need to think in stages/steps. Login is a single step, it has one of two outcomes, success or failure.
Your app needs to perform this step and take appropriate action based on the outcome of the result.
You also need to think about "separation of responsibility" - in this case, it's not really the responsibility of the loginView to perform the login operation, it just coordinates the user input.
The responsibility actually falls to the LoginModel
// Just a custom exception to make it easier to determine
// what actually went wrong
public class LoginException extends Exception {
public LoginException(String message) {
super(message);
}
}
// LoginModel ... that "does" stuff
public class LoginModel {
private String username;
DatabaseConnect db;
public LoginModel(DatabaseConnect db) {
this.db = db;
}
// I would consider not doing this. You need to ask what reasons would
// the app need this information and expose it only if there is really a
// reason to do so
public String getUsername() {
return username;
}
public boolean isLogedIn() {
return username != null;
}
public void validate(String username, String password) throws SQLException, LoginException {
String query = "select * from access where username = ? AND password = ?";
try ( Connection con = DriverManager.getConnection(db.url, db.user, db.password); PreparedStatement st = con.prepareStatement(query)) {
st.setString(1, username);
st.setString(2, password);
try ( ResultSet rs = st.executeQuery()) {
if (rs.next()) {
this.username = username;
} else {
throw new LoginException("Invalid user credentials");
}
}
}
}
}
This is an overly simplified example, as the actual responsibility for performing the login should fall to the controller, which would then generate the model, but I'm getting ahead of myself.
Because the flow of the app shouldn't be controlled/determined by the login view, the LoginView should itself be a dialog. This way, it can be shown when you need it, it can perform what ever operations it needs and then go away, leaving the rest of the decision making up to who ever called it
public class LoginView extends javax.swing.JDialog {
private LoginModel model;
public LoginView(LoginModel model) {
initComponents();
setModal(true);
this.model = model;
this.setLocationRelativeTo(null);
}
// This will get executed when the user taps some kind of "perform login button"
private void loginFunction() {
String username = usernameText.getText();
String password = passwdText.getText();
try {
model.validate(username, password);
dispose()
} catch (SQLException ex) {
// This should probably be considered a fatal error
model = null;
dispose();
} catch (LoginException ex) {
JOptionPane.showMessageDialog(this, "Login vaild");
}
}
}
This then means you might put it together something like this...
DatabaseConnect db = new DatabaseConnect();
LoginModel model = new LoginModel(db);
LoginView loginView = new LoginView(model);
// Because we're using a modal dialog, the code execution will wait here
// till the window is disposed/closed
loginView.setVisible(true);
if (loginView.model != null) {
// model is now valid and can continue to be used
// in what ever fashion you need
} else {
JOptionPane.showMessageDialog(null, "Fatal Error");
}
This takes you a step closer to a more decoupled solution, where you feed information to the classes when they need it, rather than the classes making decisions about what they should create/use.
It also moves you a step closer to re-usable classes, as they do their specific job and nothing more.
You might find taking the time to read up on "model-view-controller" will help you better understand this approach

Insert data into azure table failed

I am trying to develop a simple application for android using azure mobile services and database, I have used the following code snippets but can't seem to insert any data into my azure table.
The following is the code I used to add the data:
public void createTable(String name, String userBirthday, String email)
{
userInformationTable = mClient.getTable(UserInformation.class);
item = new UserInformation();
item.mId = "1";
item.mEmail = email;
item.mUserBirthday = userBirthday;
item.mName = name;
mClient.getTable(UserInformation.class).insert(item, new TableOperationCallback<UserInformation>()
{
public void onCompleted(UserInformation entity, Exception exception, ServiceFilterResponse response)
{
if (exception == null) {
// Insert succeeded
Log.e("Succeed", "Insert Succeeded");
} else {
// Insert failed
Log.e("Nope", "Insert Failed");
}
}
});
}
The UserInformation Class is as below:
public class UserInformation {
#com.google.gson.annotations.SerializedName("id")
public String mId;
#com.google.gson.annotations.SerializedName("name")
public String mName;
#com.google.gson.annotations.SerializedName("email")
public String mEmail;
#com.google.gson.annotations.SerializedName("user_birthday")
public String mUserBirthday;
public UserInformation(){
}
public UserInformation(String Id, String name, String email, String userBirthday)
{
}
}
There could be many different error roots for that.
Improve your log using this code, this will give you further information about the error nature.
public void createTable(String name, String userBirthday, String email)
{
userInformationTable = mClient.getTable(UserInformation.class);
if(userInformationTable == null)
{
// Insert succeeded
Log.e("Table problem", "There's no table");
}
else
{
item = new UserInformation();
item.mId = "1";
item.mEmail = email;
item.mUserBirthday = userBirthday;
item.mName = name;
userInformationTable.insert(item, new TableOperationCallback<UserInformation>()
{
public void onCompleted(UserInformation entity, Exception exception, ServiceFilterResponse response)
{
if (exception == null) {
// Insert succeeded
Log.e("Succeed", "Insert Succeeded");
} else {
// Insert failed
Log.e("Error Message", exception.getMessage());
Log.e("Error Full", exception.toString());
}
}
});
}
}}
Most probably a connection issue or less probably there aren't tables with that name.

Avoiding duplicate object properties

using a jframe i am trying to create a list of students, save them onto a file, re-read all those students and create new ones if, and only if, their id numbers are not the same. If the ID numbers are the same i am supposed to get an error message saying that that ID is already in use and thus not be able to register the new student. The only problem here is that even if the ID has already been used, it registers the students. What am i doing wrong?
import java.io.*;
import java.util.*;
import javax.swing.JOptionPane;
public class NewEstudiantesJFrame extends javax.swing.JFrame {
public static List <Estudiantes> EstReg = new ArrayList<>();
public static Long ci, ciprueba;
public NewEstudiantesJFrame() {
initComponents();
}
#SuppressWarnings("unchecked")
private void AceptarButtonActionPerformed(java.awt.event.ActionEvent evt) {
Estudiantes estu = new Estudiantes();
try {
FileInputStream fis = new FileInputStream("t.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
EstReg = (List<Estudiantes>) ois.readObject();
ois.close();// es necesario cerrar el input stream
} catch (IOException | ClassNotFoundException ex) {
}
String NumId = new String();
String tipoId = (String) TipoIdBox.getSelectedItem();
estu.TipoId = tipoId;
NumId = NumIdField.getText();
if ((NumId.length()>9)||(NumId.length()<8)){
JOptionPane.showMessageDialog(null, "Please Type in the 8 or 9 ID digits");
a++;
NumIdField.setText(null);
//NumIdField.requestFocusInWindow();
}
else
{ ci = Long.parseLong(NumId);
}
try{
**for (Estudiantes e : EstReg){
if (e.NumId == Long.parseLong(NumId)){
JOptionPane.showMessageDialog(null, "ID already in use, please check your data");
NumIdField.setText(null);
NumIdField.requestFocusInWindow();
}
else {
estu.NumId = ci;
}**
}
}
catch (NumberFormatException ex){
JOptionPane.showMessageDialog(null, "Inpult only ID numbers");
a++;
}
Here's my Estudiantes class
import java.io.Serializable;
public class Estudiantes implements Serializable{
String Nombre;
String Apellido;
String Direccion;
String Email;
String CursoActual;
String TipoId;
Long NumId;
String IdTotal;
String CodTel;
Long NumTel;
}
Thanks
Not sure if this will work but try using .compareTo() when comparing both of the longs instead of ==. Then check to see if the resulting value is equal zero.
https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#compareTo-java.lang.Long-
Sorry my bad, i just realized i hadn't shown the rest of the code... Really sorry about that. I had to take a previous version of the same file and go with the .compareTo option. Thanks for the link Bryan Herrera.
import java.io.*;
import java.util.*;
import javax.swing.JOptionPane;
public class NewEstudiantesJFrame extends javax.swing.JFrame {
public static List <Estudiantes> EstReg = new ArrayList<>();
public NewEstudiantesJFrame() {
initComponents();
}
#SuppressWarnings("unchecked")
private void AceptarButtonActionPerformed(java.awt.event.ActionEvent evt) {
Estudiantes estu = new Estudiantes();
try {
FileInputStream fis = new FileInputStream("C:\\t.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
EstReg = (List<Estudiantes>) ois.readObject();
ois.close();
} catch (IOException | ClassNotFoundException ex) {
}
String NumId = new String();
String nombre = new String();
String numTel = new String();
nombre = NombreField.getText();
String apellido = ApellidoField.getText();
String direccion = DireccionArea.getText();
String codtel;
boolean curso;
curso = false;
int a = 0;
String tipoId = (String) TipoIdBox.getSelectedItem();
estu.TipoId = tipoId;
if ((nombre.length()== 0)|| apellido.isEmpty()){
JOptionPane.showMessageDialog(null, "Please type in students full name");
a++;
}
else{
estu.Nombre = NombreField.getText();
estu.Apellido = ApellidoField.getText();
if (direccion.length()== 0){
JOptionPane.showMessageDialog(null, "Please input Student's address");
a++;
}
else{
estu.Direccion = DireccionArea.getText();}
}
try {
NumId = NumIdField.getText();
if ((NumId.length()!=8)){
JOptionPane.showMessageDialog(null, "Please type in the 8 digits if your ID");
a++;
NumIdField.setText(null);
else{
estu.NumId = Long.parseLong(NumId);
}
}
catch (NumberFormatException ex){
JOptionPane.showMessageDialog(null, "Inpult only ID numbers");
a++;
}
for (Estudiantes es: EstReg){
if (es.NumId.compareTo(estu.NumId)==0){
JOptionPane.showMessageDialog(null,"ID already in use, please check your data");
NumIdField.setText(null);
a++;
}
}
try {
numTel = NumTelField.getText();
if (numTel.length()!=7){
JOptionPane.showMessageDialog(null, "Please type in the 7 telephone number digits");
a++;
}
else
estu.NumTel = Long.parseLong(numTel);
}
catch (NumberFormatException ex){
JOptionPane.showMessageDialog(null, "Error. Only accepts numbers");
NumTelField.setText(null);
a++;
}
if (jRadioButton1.isSelected()){
estu.CursoActual= "Maths 1";
curso = true;
}
if (jRadioButton2.isSelected()){
estu.CursoActual ="Maths 2";
curso = true;
}
if (jRadioButton3.isSelected()){
estu.CursoActual ="Maths 3";
curso = true;
}
if ((curso == false) || (a > 0)){
JOptionPane.showMessageDialog(null, "Please finish filling the form out");
}
else{
ObjectOutputStream oos = null;
try {
JOptionPane.showMessageDialog(null, "Student succesfully registered. Thank you!");
estu.IdTotal = tipoId + NumId;
EstReg.add(estu);
FileOutputStream fos = new FileOutputStream("C:\\t.txt");
oos = new ObjectOutputStream(fos);
oos.writeObject(EstReg);
oos.close();
this.dispose();
} catch (Exception ex) {
}
}
}

How do I display user information to another class after logging in?

I'm having problems on how to connect my two classes. What I want to happen is, when the user logs in, the GradingSystem class will run and automatically display the user's information based on my MS ACCESS database. Somehow, I have no idea how to call or connect Login class to the other class.
LOGIN CLASS
private class ButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
DatabaseDriver driver = new DatabaseDriver();
Object source = e.getSource();
if (source == btnLogin) {
try {
String username = txtUserName.getText();
String password = String.valueOf(txtPassword.getPassword());
String query =
"Select username,password from [useraccount] where [username]='"
+ username + "' and [password]='" + password+"'";
driver.selectQuery(query);
ResultSet rsLogin = driver.rs;
if (rsLogin.next()) {
String logo = "img/seal_TIP.png";
java.net.URL addURL = getClass().getClassLoader().getResource(logo);
ImageIcon image1 = new ImageIcon(addURL);
JOptionPane.showMessageDialog(null, "Welcome to your TIP account.",
"Login Success", JOptionPane.INFORMATION_MESSAGE, image1);
dispose();
new GradingSystem().run();
} else {
JOptionPane.showMessageDialog(null, "Incorrect Username or Password.",
"User Not Found!", JOptionPane.INFORMATION_MESSAGE);
}
} catch (SQLException ex) {
}
GRADINGSYSTEM CLASS
DatabaseDriver driver = new DatabaseDriver();
String query = "Select lastName from [useraccount] where [username]='"
+login.username+"' and [password]='"+login.password+"'";
driver.selectQuery(query);
ResultSet rsGradingSystem = driver.rs;
try {
if (rsGradingSystem.next()) {
JLabel studName= new JLabel("Name: ");
studName.setBounds(15,60,150,20);
add(studName);
}
} catch (SQLException ex) {
}
You can use some static fields in your login class, and fill them after logging in, then in GradingSystem class you can use them.
something like:
public static string UserName;
public static string Password;
and in GradingSystem use:
DatabaseDriver driver = new DatabaseDriver();
String query = "Select lastName from [useraccount] where [username]='"+Login.UserName+"' and [password]='"+Login.Password+"'";
driver.selectQuery(query);
ResultSet rsGradingSystem = driver.rs;
try {
if (rsGradingSystem.next()) {
JLabel studName= new JLabel("Name: ");
studName.setBounds(15,60,150,20);
add(studName);
}
} catch (SQLException ex) {
}
don't forget to fill them after logging in.

Questions about casting

I am trying to make a game with auth system in Java. When I am trying to run it, i can see an exception thrown in the console log but there is no error in the project. I know this is runtime error
The console log displays the following information:
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to Auth$Profile
at Auth.<init>(Auth.java:30)
Here is my code:
public Auth(File profilesFile) {
try {
ProfilesJSON e = (ProfilesJSON)this.gson.fromJson(new FileReader(profilesFile), ProfilesJSON.class);
Map ps = e.authenticationDatabase;
Iterator var5 = ps.keySet().iterator();
while(var5.hasNext()) {
String name = (String)var5.next();
Profile p = (Profile)ps.get(name);
if(p != null) {
if(p.displayName == null || p.displayName.length() == 0) {
p.displayName = p.username;
}
this.profiles.add(p);
}
}
} catch (FileNotFoundException var7) {
;
} catch (NullPointerException var8) {
;
}
}
public class Profile {
public String username;
public String password;
public String uid;
public String displayName;
public String name;
public String playerUID;
public Profile(String u, String t, String id, String d) {
this.username = u;
this.password = t;
this.uid = id;
this.displayName = d;
}
}
public class ProfilesJSON {
public Map profiles;
public String selectedProfile;
public String password;
public Map authenticationDatabase;
}
Line 30 is:
Profile p = (Profile)ps.get(name);
This is a part of my code, my idea is if the player press "Remember Password", the game will generate a .json file to store his infomation..I just want to know what I did wrong, other code i can write it myself
Your ps.get(name) is returning a com.google.gson.internal.LinkedTreeMap object instead of Profile.
try to change it to:
LinkedTreeMap p = (LinkedTreeMap )ps.get(name);
Your code doesn't show you errors because there's no error in compile time, ClassCastException is a runtime exception.

Categories