JMU JMU - Department of Computer Science
Help Tools
Lab: Gaining Experience with Serialization


Instructions: Answer the following questions one at a time. After answering each question, check your answer (by clicking on the check-mark icon if it is available) before proceeding to the next question.

Getting Ready: Before going any further, you should:

  1. Setup your development environment.
  2. Depending on your development environment, create either a directory or a project for this lab.
  3. Download the following files:
    to an appropriate directory/folder. (In most browsers/OSs, the easiest way to do this is by right-clicking/control-clicking on each of the links above and then selecting Save as... or Save link as....)

1. In Case You Haven't Learned About Serialization: If you haven't learned about serialization in Java, you should read the , lecture notes on the topic.
2. Getting Caught Up: This lab is a simulation of a part of the process that is being used to create a product named TaxEze for the (hypothetical) company FreeMarket. The team is using an incremental process known as Scrum, which divides the work up into sprints. Since you weren't involved in the earlier sprints, you have some catching up to do.
  1. Read the sprintable stories from the previous sprint. (Note that not all of the acceptance criteria were satisfied in the previous sprint. The tasks required to complete those product backlog items are someone else's responsibility. You should be able to complete your tasks independently.)
  2. Review the UML class diagram that was created during the previous sprint. (Note that the UML class diagram is fairly abstract.)
  3. Create a project in your IDE.
  4. Copy the existing code into the src directory/folder in your IDE. (Note that the code is in several packages, one of which contains JUnit tests. If you copy the directories/folders from a file explorer and paste them into your IDE, it will create the appropriate packages for you.)
  5. Un-zip the .tax files from US2019.zip and put them in a convenient location (outside of the project).
  6. Un-zip the icons from icons.zip and put them in a convenient location (outside of the project).
  7. Copy the icons into the project directory/folder inside of the IDE.
  8. Run the JUnit tests to ensure that the TaxTable class is working. (Note: You will first need to change the PATH in the test of the read() method.
  9. Run the Taxeze application to ensure that it is working.
  10. Read the sprintable stories for this sprint.

Note that this lab is part of a sequence, so you should save your work -- you may need it later.

3. A Brief Review of Serialization in Java: This part of the lab will help you remember some of what you've learned about serialization in Java.
  1. What interface must a class implement in order for its objects to be serializable?
    java.io.Serializable
    
    Expand
  2. Which class or classes in Taxeze must implement this interface?
    Obviously the TaxSchedule class must. But, since it extends HashMap it already does. However, to make it explicit, its useful to add it to the declaration of the class. In addition, since TaxSchedule contains references to TaxTable, TaxTable must also implement Serializable.
    Expand
  3. What is the point of the static serialVersionUID attribute?
    It allows the de-serializer to compare the version of the serialized object with the version of the class to ensure that they are the same.
    Expand
  4. What method in what class can be used to serialize Serializable objects?
    The writeObject() method in the ObjectOutputStream class.
    Expand
  5. What method in what class can be used to deserialize Serializable objects?
    The readObject() method in the ObjectInputStream class.
    Expand
  6. What kinds of objects are returned by the de-serializing method?
    Object objects.
    Expand
  7. As a result, what must be done to the objects it returns?
    They must be typecast.
    Expand
4. Tasks: The sprintable stories have been decomposed into the following tasks that you must complete for this lab.
  1. Declare all of the appropriate classes to be Serializable.
  2. Add a method with the signature:
        public void write(String filename) throws IOException
        

    to the TaxSchedule class that serializes the owning object.

      public void write(String filename) throws IOException
      {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename + ".txs"));
        
        out.writeObject(this);
        out.flush();
        out.close();
      }
    
    Expand
  3. Add a method with the signature:
        public static TaxSchedule open(String filename) throws IOException
        

    to the TaxSchedule class that reads a serialized TaxSchedule object.

      public static TaxSchedule open(String filename) throws IOException
      {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename + ".txs"));
        TaxSchedule schedule;
        try
        {
          schedule = (TaxSchedule)in.readObject();
        }
        catch (ClassNotFoundException cnfe)
        {
          schedule = new TaxSchedule("Unknown");
        }
        in.close();
        
        return schedule;
      }
    
    Expand
  4. Add a SerializationTests class to the testing package that tests these new methods.
    It should look something like the following.
    package testing;
    
    import static org.junit.jupiter.api.Assertions.*;
    
    import java.io.*;
    import tax.*;
    import org.junit.jupiter.api.Test;
    
    class SerializationTests
    {
      private static final String PATH = "CHANGE ME";
    
      @Test
      public void roundTrip() throws IOException
      {
        TaxSchedule   schedule = new TaxSchedule("US");
        TaxTable table;
        String name;
        
        name = "Single_2019";
        table = new TaxTable();
        table.read(PATH + name);
        schedule.put(name, table);
        
        name = "Married-Filing-Jointly_2019";
        table = new TaxTable();
        table.read(PATH + name);
        schedule.put(name, table);
        
        schedule.write(PATH + "test");
        
        schedule = TaxSchedule.open(PATH + "test");
        
        table = schedule.get("Single_2019");
        assertEquals(12.56467, table.getInterpolatedRate(42000.50), 0.001);
      }
    }
    
    Expand
  5. Perform regression testing using the pre-existing unit tests to ensure you didn't introduce any defects into the code that was working.
  6. Have you satisfied all of the acceptance criteria?
    No, I haven't added the GUI components and I haven't conducted the system tests. I'll do that as part of another lab.
    Expand

Copyright 2021