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 Wherez for the (hypothetical) company Nearby. 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 .seg and .int files from harrisonburg.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. Change PATH_TO_HARRISONBURG_NETWORK in Test_AddressGeocoder so that it points to the location of the .seg file.
  9. Run the JUnit tests to ensure that the AddressGeocoder is working.
  10. Run the Wherez application to ensure that it is working.
  11. 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 Wherez must implement this interface?
    Obviously the StreetNetwork class must. But, since it contains references to Street, Interesection, and NameComparator objects, they must also. Finally, since the Street class contains references to StreetSegment objects it must too.
    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 StreetNetwork class that serializes the owning object.

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

    to the StreetNetwork class that reads a serialized StreetNetwork object.

      public static StreetNetwork open(String filename) throws IOException
      {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename + ".snk"));
        StreetNetwork     network;
        try
        {
          network = (StreetNetwork)in.readObject();
        }
        catch (ClassNotFoundException cnfe)
        {
          network = new StreetNetwork();
        }
        in.close();
        
        return network;
      }
    
    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 geocoding.*;
    import java.io.*;
    import network.*;
    import org.junit.jupiter.api.Test;
    
    class SerializationTests
    {
      private static final String PATH = "CHANGE ME";
    
      @Test
      public void roundTrip() throws IOException
      {
        StreetNetwork   network;
        network = StreetNetwork.read(PATH + "harrisonburg");
        network.write(PATH + "test");
        network = StreetNetwork.open(PATH + "test");
        
        double[]        actual;
        int             number;
        String          canonicalName;
        AddressGeocoder geocoder = new AddressGeocoder(network);
        
        number = 244;
        canonicalName = Street.createCanonicalName("N", "Main", "St", null);
        actual = geocoder.getCoords(canonicalName, number);
        assertEquals(-78.86796131, actual[0], 0.001, "Longitude");
        assertEquals( 38.45183357, actual[1], 0.001, "Latitide");
      }
    }
    
    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