Not Serializable Exception [duplicate] - exception

This question already has answers here:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException
(2 answers)
Closed 5 years ago.
i am trying to create a mock shopping cart for a uni project. im using two java classes Item and shoppingCart, shopping cart uses a vector to store Items and then writes them to a file. i am trying to use the classes on a jsp page but when i try to write to the file i get an java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: cart.Item... any ideas how i could fix this??

From the javadoc on NotSerializableException... "Thrown when an instance is required to have a Serializable interface."
This means that your class that you're serializing need to implement the Serializable marker interface.

Here is a small Example to you...
import java.io.*;
class player implements Serializable{
String name;
double health;
double positionX;
double positionY;
int weapon;
}
class game{
public static void main(String[] args) throws Exception{
player character1 = new player();
character1.name = "Inukz";
character1.health = 82.62;
character1.positionX = 80;
character1.positionY = 33;
character1.weapon = 2;
player character2 = new player();
character2.name = "Prasad";
character2.health = 32.62;
character2.positionX = 40;
character2.positionY = 63;
character2.weapon = 3;
player character3 = new player();
character3.name = "Thilan";
character3.health = 12.62;
character3.positionX = 10;
character3.positionY = 83;
character3.weapon = 1;
FileOutputStream fileStream = new FileOutputStream("myGame.js",true);
ObjectOutputStream os = new ObjectOutputStream(fileStream);
os.writeObject(character1);
os.close();
}
}

To avoid NotSerializableException make sure:
your class implements Serializable
all non primitive members implement Serializable (or are transient instead)
if your class is an inner class it's either static or the outer class implements
Serializable
Besides that you also need to define serialVersionUID for every Serializable class. Check all 3 cases above plus:
all Serializable superclasses
if your class is an anonymous class, define it there too
Note: your code may run without serialVersionUID sometimes but read the last paragraph in Serializable's javadoc to understand why it will be a problem depending on the environment.
There's a VM option to add details to the exception. It shows the root and nested classes failing to serialize:
-Dsun.io.serialization.extendedDebugInfo=true

Related

How to load values from custom properties file for junit testing using Mockito?

I have written this test class to check a service. This is in folder test/java/example/demp/Test.java
#RunWith(MockitoJUnitRunner.class)
#TestPropertySource("classpath:conn.properties")
public class DisplayServiceTest {
#Value("${id}")
private String value;
#Mock
private DisplayRepository DisplayReps;
#InjectMocks
private DisplayService DisplayService;
#Test
public void whenFindAll_thenReturnProductList() {
Menu m = new Menu()
m.setId(value); //when I print value its showing 0
List<Display> expectedDisplay = Arrays.asList(m);
doReturn(expectedDisplay).when(DisplayReps).findAll();
List<Display> actualDisplay = DisplayService.findAll();
assertThat(actualDisplay).isEqualTo(expectedDisplay);
}
My properties file
This is in folder test/resources/conn.properties
id=2
What is the right way to set properties from custom properties file? Cause its not loading values ?
Mockito is a mocking framework, so in general you can't load properties file with Mockito.
Now you've used #TestPropertySource which is a part of Spring Testing and it indeed allows loading properties file (that have nothing to do with mockito though). However using it requires running with SpringRunner and in general its good for integration tests, not for unit tests (Spring Runner among primarily loads Spring's application context).
So if you don't want to use spring here, you should do it "manually". There are many different ways to load Properties file from class path (with getClass().getResourceAsStream() to get the input stream pointing on the resource file and the read it into Properties by using Properties#load(InputStream) for example.
You can also use other thirdparties (not mockito), like apache commons io to read the stream with IOUtils class
If you want to integrate with JUnit 4.x you can even create a rule, described here
#TestPropertySource is a spring annotation, so you need to use the SpringRunner.
You can initialize Mockito using MockitoAnnotations.initMocks(this);, check the example below.
#RunWith(SpringRunner.class)
#TestPropertySource("classpath:conn.properties")
public class DisplayServiceTest {
#Value("${id}")
private String value;
// ...
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
// ...
}
You could use just Mockito and JUnit 4. At the #Before method, call MockitoAnnotations.initMocks and load the properties file:
public class DisplayServiceTest {
private String value;
#Mock
private DisplayRepository displayReps;
#InjectMocks
private DisplayService displayService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Properties prop = loadPropertiesFromFile("conn.properties");
this.value = prop.getProperty("id");
}
private Properties loadPropertiesFromFile(String fileName) {
Properties prop = new Properties();
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream(fileName);
prop.load(stream);
stream.close();
} catch (Exception e) {
String msg = String.format("Failed to load file '%s' - %s - %s", fileName, e.getClass().getName(),
e.getMessage());
Assert.fail(msg);
}
return prop;
}
#Test
public void whenFindAll_thenReturnProductList() {
System.out.println("value: " + this.value);
Menu m = new Menu();
m.setId(this.value); // when I print value its showing 0
List<Display> expectedDisplay = Arrays.asList(m);
Mockito.doReturn(expectedDisplay).when(this.displayReps).findAll();
List<Display> actualDisplay = this.displayService.findAll();
Assert.assertEquals(expectedDisplay, actualDisplay);
}
}

How to use these #DataMongoTest and #SpringBootTest together in integration test

I am trying to write integration test case for one of my rest application which uses mongodb internally to persist the data
#DataMongoTest
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MainControllerTest {
#LocalServerPort
private int port = 8080;
/* some test cases*/
}
but I am getting below error
java.lang.IllegalStateException: Configuration error: found multiple declarations of #BootstrapWith for test class [com.sample.core.controller.MainControllerTest]: [#org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTestContextBootstrapper), #org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper)]
looks like these two are mutually exclusive, so how to do the integration testing .
Use #AutoConfigureDataMongo with #SpringBootTest and this will resolve this ambiguity issue. #SpringBootTest and #DataMongoTest cannot be used together.
Answering to a very old post hoping it may help others.
#AutoConfigureDataMongo will connect to real database. In order to still use the embedded mongo, one can initiate the embedded mongoDb manually.
#SpringBootTest(classes = SubscriptionEventApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SubscriptionEventApiIntegrationTest {
#BeforeAll
static void setup() throws Exception {
startEmbeddedMongoDbManually();
}
private static void startEmbeddedMongoDbManually() throws IOException {
final String connectionString = "mongodb://%s:%d";
final String ip = "localhost";
final int port = 27017;
ImmutableMongodConfig mongodConfig = MongodConfig
.builder()
.version(Version.V3_5_5)
.net(new Net(ip, port, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodConfig);
mongodExecutable.start();
mongoTemplate = new MongoTemplate(MongoClients.create(String.format(connectionString, ip, port)), "test");
}
#AfterAll
static void clean() {
mongodExecutable.stop();
}
#Test
public void test() {
.....
}
}
Purushothaman suggested starting embedded MongoDB server manually. I am suggesting to start it automatically using #DataMongoTest, but creating WebTestClient manually instead.
Kotlin code below, translates to Java trivially:
#DataMongoTest
// #ContextConfiguration may not be needed for your case.
#ContextConfiguration(
classes = [
Application::class,
MainController::class,
// Add more needed classes for your tests here.
// ...
]
)
#TestPropertySource(properties = ["spring.mongodb.embedded.version=4.0.12"])
class MainControllerTest(
#Autowired
private val mainController: MainController,
// Add more beans needed for your tests here.
// ...
) {
// Creating a WebTestClient is easy and
// can be done in different ways.
// Here is one of the possible ways.
private val webTestClient: WebTestClient =
WebTestClient.bindToController(mainController).build()
#Test
fun someTest() {
// ...
}
}

Referencing ResultSet/Using the Next() method

I'm using JavaFX to create a basic GUI. I have a database created in MySQL to store the data. (DBConnect) (connector/j)
This is my very first attempt at connecting the two, as well as using ResultSets/DBConnect
Currently, I have 3 Classes: my Game class, my GameUI class (main), and my DBConnect class.
I am attempting to Reference the ResultSet in my GameUI class, that was originally declared in Game class.
public class Game {
private static DBConnect dbc;
private static Connection conn;
public ResultSet rs;
int id;
String name;
float price;
String vendor;
int rating;
public Game() {
try {
conn = dbc.connect();
String SQL = "Select * from Person";
rs = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE).executeQuery(SQL);
System.out.println("list result set for record..");
printRs(rs);
} catch(SQLException ignore) {
}
}
My User Defined moveNext() method:
public Game moveNext() {
Game g = new Game();
try {
if(rs.next() == false)
rs.previous();
g.setGameId(rs.getInt("gameId"));
g.setGameName(rs.getString("gameName"));
g.setPrice(rs.getFloat("price"));
g.setVendor(rs.getString("vendor"));
g.setRating(rs.getInt("rating"));
} catch(SQLException e) {
e.printStackTrace();
}
return g;
}
The GameUI class i am trying to reference it in:
public class GameUI extends Application {
private Button firstButton = new Button("First");
private Button createButton = new Button("Create");
private Button updateButton = new Button("Update");
private Button deleteButton = new Button("Delete");
private Button lastButton = new Button("Last");
private Button nextButton = new Button("Next");
private Button prevButton = new Button("Prev");
GridPane grid = new GridPane();
HBox hbox = new HBox(14);
private static DBConnect dbc;
private static Connection conn;
// private static
private Pane initButtons() {
hbox.getChildren().addAll(firstButton, createButton, updateButton, deleteButton, lastButton, nextButton, prevButton);
nextButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
Game.rs.moveNext();
}
});
return hbox;
}
My Question is, can I Reference my ResultSet (Game class) in my nextButton event handler (my GameUI class) OR do I have to declare a new result set?
Is this the right place for my user defined moveNext() method, or should I use next()?
I will post more code on request.
You can pass the result set further, but it is bad practice (See Is it Ok to Pass ResultSet?). From what I see from the code you posted it is mainly an issue with the layering of the different parts of the application, that should be separated:
Database related code belong into one layer. No other layer should directly talk to the DB or handle any DB specific objects. To achieve this the DBConnection class should handle all database related stuff. To pass data from the database to the other layers and vice versa you use a data transfer object (DTO) which is basically an object representation of a specific result set. Usually this boils down to one DTO per database table.
Then you have an intermediate layer, lets call it service layer, which is used to communicate from the UI to the database and do some computation.
On top of that you have the UI layer where your application lives. Here you have to consider which actions belong into that layer and what should better be delegated to the service layer.
Take also a look at this wikipedia article: https://en.wikipedia.org/wiki/Multitier_architecture

How can I do asynchrous database in JavaFX [duplicate]

This question already has answers here:
JavaFX - Background Thread for SQL Query
(2 answers)
Closed 8 years ago.
I have a question. How can I do asynchrous database in JavaFX. I know that exist SwingWoker but I read that I can't use this in JavaFX. I read about Task but I can do convert the result to ObservableList but I need normal LinkedList.
I'm trying conntect to mysql database
I know that this forum has a lot of answering about database in javafx but all results are converted to ObservableList
Thank you for all the answers.
FlightControllerTask.java
public class FlightControllerTask extends Task<LinkedList<Flight>>{
private final static int MAX=10000;
ArrayList<Airport> airportList=new ArrayList<>()
#Override
protected LinkedList<Flight> call() throws Exception {
for (int i = 0; i < MAX; i++) {
updateProgress(i, MAX);
Thread.sleep(5);
}
LinkedList<Flight> flightList = new LinkedList<>();
Connection c ;
c = DBConnector.connect();
String SQL = "SELECT flight.idflight, airport.nameAirport, airport.nameAirport, flight.departureTime FROM flight INNER JOIN airport";
ResultSet rs = c.createStatement().executeQuery(SQL);
while(rs.next()){
flightList.add(new Flight(rs.getInt("idflight"), rs.getString("flightFrom"), rs.getString("flightTo"), rs.getTime("departureTime")));
}
return flightList;
}
FlightControllerService
public class FlightControllerService extends Service<LinkedList<Flight>>{
#Override
protected Task<LinkedList<Flight>> createTask() {
return new FlightControllerTask();
}
}
MainController.java
final FlightControllerService service= new FlightControllerService();
ReadOnlyObjectProperty<LinkedList<Flight>> flightList =service.valueProperty();
flightList.get();
public class FlightControllerTask extends Task<LinkedList<Flight>>{
#Override
protected LinkedList<Flight> call() throws Exception {
// load data
return data;
}
}
// usage:
FlightControllerTask task = new FlightControllerTask();
task.setOnSucceeded(ev -> task.getValue());
new Thread(task).start();
Now the part with task.getValue() is the crucial part, with this method you can retrieve the value that was computed with the task as soon as is is ready (thus the succeeded hook).

Trouble getting desired json output with JacksonJaxbJsonProvider

I'm using the latest Jackson (2.2.3) with a CXF application.
Here is my Jackson provider:
public class CustomJacksonJsonProvider extends JacksonJaxbJsonProvider {
public CustomJacksonJsonProvider() {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
JaxbAnnotationModule jaxbModule = new JaxbAnnotationModule();
mapper.registerModule(jaxbModule);
this._mapperConfig.setMapper(mapper);
}
}
I have the following annotated class.
#XmlType(name = "configInfo")
#XmlRootElement(name = "configInfo")
public class ConfigInfo {
#XmlElement(name = "foo")
private String foo;
#XmlElementWrapper(name = "devices")
#XmlElement(name = "device")
private List<Device> devices;
public final List<Device> getDevices() {
if (devices == null)
devices = new ArrayList<Device>();
return devices;
}
}
I created an instance with no "foo" value, and one device in the devices list. When I render this, I get the following:
{"device":[{"name":"abc","type":"def"}]}
How can I make "device" render as "devices"?
I've managed to figure this out. The key realization is that if the JAXB annotations are confusing Jackson, then perhaps I should just have Jackson ignore them. I simply removed the registration of the "JaxbAnnotationModule" and now both my JSON and XML output are sane. I now need to consider whether it makes any sense to use "JacksonJaxbJsonProvider" as opposed to a simpler provider.