Package Torello.Java

Class LFEC


  • public class LFEC
    extends java.lang.Object
    Load File Exception Catch provides an eloquent way for printing standardized (consistent-looking) error messages to terminal if a data-file fails to load from the file-system, and subsequently halting the JVM - immediately.

    LFEC: Load File Exception Catch

    The primary reason for this class is to prevent continuing, and ensure that as much relevant information is printed in the event of a lost or corrupted data-file. Generally, if a data-file does not load, it is best to halt the program immediately, and completely. Load File Exception Catch halts the program, prints exception information, and then just calls Java's System.exit(0); command.


    Invokes System.exit(int)
    This call will invoke System.exit(1) whenever an error occurs while attempting to load a file from disk or from a JAR. The meaning of the letters 'EC' in this class' name-acronym is Exception-Catch. The reason that exceptions are caught is to prevent a user from catching-them, and continuing on with his or her Java Program (and possibly producing erroneous results, because said data-files were not loaded).


    Load Resource as Stream:
    Methods in this class that contain the acronym JAR will use the "load resource as stream" feature provided by the JVM. This feature allows a programmer to retrieve data from a JAR-File rather than the standard file i/o system. The line of code snippet below is just a reminder of how to use the getResourceAsStream(String) method which is provided by class java.lang.Class.

    BufferedReader br = new BufferedReader(new InputStreamReader(c.getResourceAsStream(f)));
    




    Below is an example of where best to use this class and its methods. The Java HTML JAR Library Tool Syntax HiLiter requires several data-files to be loaded by that class. These contents of these datafiles, which are loaded out of the JAR-File, are assigned to static and final fields declared within that class.

    Example:
    // It is required that the text-file "myDataFile.txt" is located in the same directory
    // as the ".java" and ".class" file as "this" (object) is.  This line will halt program
    // execution if loading fails.
    
    String dataFileStr = LFEC.loadFile_JAR(this.class, "myDataFile.txt");
    
    // Print the contents of the data file to the terminal.
    System.out.println("Data File Contains:\n" + dataFileStr);
    
    // THIS EXAMPLE IS FOUND IN THE HiLiteMe class - How to load a data-file, and make sure
    // error-information is printed, or halting immediately and printing a standardized error
    // message.
    public class HiLiteMe
    ...
        // ***************************************************************************************
        // HiLite.ME parameter-tags stored internally.
        // ***************************************************************************************
        private static final Vector<Object> dataFile = (Vector<Object>) LFEC.readObjectFromFile_JAR
            (Torello.Data.DataFileLoader.class, "data06.vdat", true, Vector.class.getName());
        
        private static final TreeMap<String, String> codeTypeDescriptions =
            (TreeMap<String, String>) dataFile.elementAt(0);
    
        private static final Vector<String> styleTypes = (Vector<String>) dataFile.elementAt(1);
    



    Reading JavaDoc:
    It might be important to read the Java Doc's about the java.lang.Class.getResourceAsStream(String) method for retrieving data that was stored to a JAR file instead of a UNIX/BASH/MS-DOS system file.



    Stateless Class:
    This class neither contains any program-state, nor can it be instantiated. The @StaticFunctional Annotation may also be called 'The Spaghetti Report'. Static-Functional classes are, essentially, C-Styled Files, without any constructors or non-static member fields. It is a concept very similar to the Java-Bean's @Stateless Annotation.

    • 1 Constructor(s), 1 declared private, zero-argument constructor
    • 9 Method(s), 9 declared static
    • 0 Field(s)


    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class
      static class  LFEC.GCSSB
    • Method Summary

       
      Loading Text Files to memory
      Modifier and Type Method
      static String loadFile​(String f)
      static String loadFile_JAR​(Class<?> classLoaderClass, String f)
      static Vector<String> loadFileToVector​(String f, boolean includeNewLine)
      static Vector<String> loadFileToVector_JAR​(Class<?> classLoaderClass, String f, boolean includeNewLine)
       
      Loading Java Serializable-Object Files to memory
      Modifier and Type Method
      static <T> T readObjectFromFile​(String f, boolean zip, Class<T> returnClass)
      static <T> T readObjectFromFile_JAR​(Class<?> classLoaderClass, String f, boolean zip, Class<T> returnClass)
       
      Extracting & Copying a File from a JAR to disk
      Modifier and Type Method
      static void copyFile_JAR​(Class<?> classLoaderClass, String fileName, String targetFileName)
       
      Internal, Protected Methods
      Modifier and Type Method
      protected static void ERROR_EXIT​(String message)
      protected static void ERROR_EXIT​(Throwable t, String message)
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • ERROR_EXIT

        🡇     🗕  🗗  🗖
        protected static void ERROR_EXIT​(java.lang.Throwable t,
                                         java.lang.String message)
        This prints a message and a location and halts the current thread immediately. (Halts the program) The entire rational behind the class LFEC is to facilitate loading data-files, and forcing an immediate program halt if this operation fails. Generally, during development and debugging, failing to read from a data-file is serious enough to warrant stopping the software until the issue is fixed. "Hobbling along without reading the data-files" makes little sense.

        When the software is being released or distributed, the philosophy turns to loading mission critical data out of data-files in a java jar-file. If the jar-file is corrupted and those files are not present, generally this situation would also warrant halting the program execution immediately until the jar file is fixed.
        Parameters:
        t - An exception, error or other Throwable that generated a problem when attempting to read a data-file.
        message - This is an internally generated message explaining what has occurred.
        Code:
        Exact Method Body:
         System.out.println(
             '\n' +
             "There was an error loading a data-file, and program-execution is being halted " +
             "immediately.\n" +
             "Problem Encountered With:\n" + StrIndent.indent(message, 4) + "\n" +
             "Exception or Error Message:\n" +
             EXCC.toString(t) + "\n\n" +
             "Exiting Program, Fatal Error Loading Critical Data File."
         );
        
         System.exit(1);
        
      • ERROR_EXIT

        🡅  🡇     🗕  🗗  🗖
        protected static void ERROR_EXIT​(java.lang.String message)
        This prints a message and a location and halts the current thread immediately. (Halts the program) The entire rational behind the class LFEC is to facilitate loading data-files, and forcing an immediate program halt if this operation fails. Generally, during development and debugging, failing to read from a data-file is serious enough to warrant stopping the software until the issue is fixed. "Hobbling along without reading the data-files" makes little sense.

        When the software is being released or distributed, the philosophy turns to loading mission critical data out of data-files in a java jar-file. If the jar-file is corrupted and those files are not present, generally this situation would also warrant halting the program execution immediately until the jar file is fixed.
        Parameters:
        message - This is an internally generated message explaining what has occurred.
        Code:
        Exact Method Body:
         System.out.println(
             '\n' +
             "There was an error loading a data-file, and program-execution is being halted " +
             "immediately.\n" +
             "Problem Encountered With:\n" + message + "\n\n" +
             "Exiting Program, Fatal Error Loading Critical Data File."
         );
        
         System.exit(1);
        
      • loadFile

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String loadFile​(java.lang.String f)
        Loads a file directly into a java-String. If this file fails to load, it halts the run-time environment.
        Parameters:
        f - This is a java.lang.String that contains the filename.
        Returns:
        The returned String contains the entire contents of the file.
        See Also:
        FileRW.loadFileToString(String), ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         try
             { return FileRW.loadFileToString(f); }
        
         catch (Throwable t)
             { ERROR_EXIT(t, "FileRW.loadFileToString(\"" + f + "\")");  }
        
         throw new UnreachableError(); // Should not be possible to reach this statement
        
      • loadFile_JAR

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String loadFile_JAR​
                    (java.lang.Class<?> classLoaderClass,
                     java.lang.String f)
        
        Loads a file directory to a string from a java jar-file. It halts the program, and prints a detailed message if any Error's or Exception's were thrown. The directory inside the jar-file where this file may be located identified by parameter class 'classLoaderClass'.
        Parameters:
        classLoaderClass - This contains the 'class' that will be used by Java's java.lang.Class.getResourceAsStream(...) method. Please see the comments at the top of this class-documentation page for a better explanation of how Java's class-loader uses a 'java.lang.Class<E>' object to find data-files (which java calls 'resources') inside of a jar-file.

        All that is really going on is that as classes are loaded by the class-loader from the file-system and from jar-files - the class-loader actually remembers which jar-file's and which directories inside the jar-files contained any/all class-definitions ('.class' files) that were loaded from jar files instead of the file-system.

        This parameter class 'c' points to a jar-file and directory combination that will contain the date-file named/identified by the next parameter String 'f'.

        NOTE: The symbols <?> appended to the (almost) 'raw-type' here, are only there to prevent the java-compiler from issuing warnings regarding the use of "Raw Types." This warning is, actually, only issued if the command-line option -Xlint:all option is used.
        f - This is a String that contains the filename of the data-file that needs to be loaded. It is a 'relative file-name' that is relative to the jar-file / directory pair location that the class loader identifies using the Class from parameter 'classLoaderClass'
        Returns:
        The returned string contains the entire contents of the file.
        See Also:
        ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         // These are 'java.lang.AutoCloseable', and java handles them automatically
         // if there is an exception
        
         try (
             InputStream     is  = classLoaderClass.getResourceAsStream(f);
             BufferedReader  br  = new BufferedReader(new InputStreamReader(is));
         )
         {
             String          s   = "";
             StringBuffer    sb  = new StringBuffer();
        
             while ((s = br.readLine()) != null) sb.append(s + "\n");
        
             return sb.toString();
         }
        
         catch (Throwable t)
         {
             ERROR_EXIT(
                 t,
                 "Error loading text-file [" + f + "] from jar-file.\n" +
                 "Class loader attempted to use information in class " +
                 "[" + classLoaderClass.getCanonicalName() + "], but failed."
             );
         }
        
         throw new UnreachableError(); // Should NOT be possible to reach this statement...
        
      • copyFile_JAR

        🡅  🡇     🗕  🗗  🗖
        public static void copyFile_JAR​(java.lang.Class<?> classLoaderClass,
                                        java.lang.String fileName,
                                        java.lang.String targetFileName)
        Loads a file from a java jar-file using an InputStream and copies that file, byte-for-byte, to 'targetFileName'. A detailed message is printed if any Error's or Exception's were thrown. The directory inside the jar-file where this file may be located identified by parameter class 'classLoaderClass'.
        Parameters:
        classLoaderClass - This contains the 'class' that will be used by Java's java.lang.Class.getResourceAsStream(...) method. Please see the comments at the top of this class-documentation page for a better explanation of how Java's class-loader uses a 'java.lang.Class<E>' object to find data-files (which java calls 'resources') inside of a jar-file.

        All that is really going on is that as classes are loaded by the class-loader from the file-system and from jar-files - the class-loader actually remembers which jar-file's and which directories inside the jar-files contained any/all class-definitions ('.class' files) that were loaded from jar files instead of the file-system.

        This parameter class 'c' points to a jar-file and directory combination that will contain the date-file named/identified by the next parameter String 'f'.

        NOTE: The symbols <?> appended to the (almost) 'raw-type' here, are only there to prevent the java-compiler from issuing warnings regarding the use of "Raw Types." This warning is, actually, only issued if the command-line option -Xlint:all option is used.
        fileName - This is a String that contains the filename of the data-file that needs to be copied. It is a 'relative file-name' that is relative to the jar-file / directory pair location that the class loader identifies using the Class from parameter 'classLoaderClass'.
        targetFileName - This is the file and directory that contains the target location (as a String) to where the file should be copied.
        See Also:
        ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         // These are 'java.lang.AutoCloseable', and java handles them automatically
         // if there is an exception
        
         try (
             InputStream         is  = classLoaderClass.getResourceAsStream(fileName);
             FileOutputStream    fos = new FileOutputStream(targetFileName);
         )
         {
             byte[]  b       = new byte[5000];
             int     result  = 0;
            
             while ((result = is.read(b)) != -1) fos.write(b, 0, result);
         }
        
         catch (Throwable t)
         {
             ERROR_EXIT(
                 t,
                 "Error copying file [" + fileName + "] from jar-file to " +
                 "[" + targetFileName + "].\n" +
                 "Class loader attempted to use information in class " +
                 "[" + classLoaderClass.getCanonicalName() + "]."
             );
         }
        
      • loadFileToVector

        🡅  🡇     🗕  🗗  🗖
        public static java.util.Vector<java.lang.String> loadFileToVector​
                    (java.lang.String f,
                     boolean includeNewLine)
        
        This loads a file to a Vector of String's. It halts the program, and prints a detailed message if any errors or exceptions occur.
        Parameters:
        f - The name of the file to load
        includeNewLine - States whether the '\n' (new-line) character should be appended to each element of the returned Vector<String>.
        Returns:
        a Vector of String's, where each element in the Vector is a line retrieved from the text-file.
        See Also:
        ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         try
             { return FileRW.loadFileToVector(f, includeNewLine); }
        
         catch (Throwable t)
         {
             ERROR_EXIT(
                 t, 
                 "Attempting to Invoke this Load-Method with these Arguments:\n" +
                 "FileRW.loadFileToVector(\"" + f + "\", " + includeNewLine + ");"
             );
         }
        
         throw new UnreachableError(); // Should NOT be possible to reach this statement...
        
      • loadFileToVector_JAR

        🡅  🡇     🗕  🗗  🗖
        public static java.util.Vector<java.lang.String> loadFileToVector_JAR​
                    (java.lang.Class<?> classLoaderClass,
                     java.lang.String f,
                     boolean includeNewLine)
        
        This loads a file to a Vector of String's. It halts the program, and prints a detailed message if any Error's or Exception's occur. The directory inside the jar-file where this file may be located identified by parameter 'classLoaderClass'.
        Parameters:
        classLoaderClass - This contains the 'class' that will be used by Java's java.lang.Class.getResourceAsStream(...) method. Please see the comments at the top of this class-documentation page for a better explanation of how Java's class-loader uses a 'java.lang.Class<E>' object to find data-files (which java calls 'resources') inside of a jar-file.

        All that is really going on is that as classes are loaded by the class-loader from the file-system and from jar-files - the class-loader actually remembers which jar-file's and which directories inside the jar-files contained any/all class-definitions ('.class' files) that were loaded from jar files instead of the file-system.

        This parameter class 'c' points to a jar-file and directory combination that will contain the date-file named/identified by the next parameter String 'f'.

        NOTE: The symbols <?> appended to the (almost) 'raw-type' here, are only there to prevent the java-compiler from issuing warnings regarding the use of "Raw Types." This warning is, actually, only issued if the command-line option -Xlint:all option is used.
        f - This is a String that contains the filename of the data-file that needs to be loaded. It is a 'relative file-name' that is relative to the jar-file / directory pair location that the class loader identifies using the Class from parameter 'classLoaderClass'.
        includeNewLine - States whether the '\n' (newline) character should be appended to each element of the Vector.
        Returns:
        a Vector of String's, where each element in the Vector is a line retrieved from the text-file.
        See Also:
        ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         // These are 'java.lang.AutoCloseable', and java handles them automatically
         // if there is an exception
        
         try (
             InputStream     is  = classLoaderClass.getResourceAsStream(f);
             BufferedReader  br  = new BufferedReader(new InputStreamReader(is));
         )
         {
             String          s   = "";
             Vector<String>  ret = new Vector<>();
        
             if (includeNewLine)
                 while ((s = br.readLine()) != null)
                     ret.addElement(s + '\n');
        
             else
                 while ((s = br.readLine()) != null)
                     ret.addElement(s);
        
             return ret;
         }
        
         catch (Throwable t)
         {
             ERROR_EXIT(
                 t,
                 "Error loading text-file [" + f + "] from jar-file.\n" +
                 "Parameter includeNewLine was: " + includeNewLine + "\n" +
                 "Class loader attempted to use information in class " +
                 "[" + classLoaderClass.getCanonicalName() + "], but failed."
             );
         }
        
         throw new UnreachableError(); // Should NOT be possible to reach this statement...
        
      • readObjectFromFile

        🡅  🡇     🗕  🗗  🗖
        public static <T> T readObjectFromFile​(java.lang.String f,
                                               boolean zip,
                                               java.lang.Class<T> returnClass)
        This loads a java.lang.Object from a data-file.

        Serializable Containers:
        This method will load ONLY ONE java.lang.Object out of the data-file from inside the '.jar' File. If you wish to save multiple Object's to a data-file, the best way to achieve this is to put however many Serializable-Object's you have into a Java Serializable-Container (such as java.util.Vector), and then save that container as a Serialized-Object File.

        There will be (just a modicum) of effort needed to 'cast' an Object that has been retrieved from a Serialized-Object Data-File into a Java POJO. It is usually well worth since Data Read/Write Operations are tremendously simplified due to the work done for the Serializable inteface.

        Generic Erasure:
        Java's Generic Classes (where a Type-Parameter such as 'E' is used - as in java.util.Vector<E>) do not preserve the chosen-types at runtime. Instead, at Compile-Time, the Java-Compiler will often issue warnings and errors to flag things that it doesn't like.

        Whenever working with Java-Generics, it is most important to remember that the only purpose whatsoever behind using them at all are for the Compile-Time Warning & Error Messages that they provide. Once RunTime has started, the Java Run-Time Environment doesn't know anything about the Types in it's Generic-Classes.

        Raw-Types Warnings:
        On such Compiler-Warning that is often generated is the Raw-Types Warning. When attempting to cast a Raw-Type to it's 'specified-type' after de-serializing a Java Object, it will be necessary to use the @SuppressWarnings("unchecked") Annotation to read & de-serialize Java Generics from disk.

        This will be required regardless of "how sure you are" that the type being read is, indeed, the type to which it is being assigned.

        Example:
        // Use the following Java 'Annotation' (Suppress Warnings)
        // This will allow the programmer to cast the "Raw-Type" Vector, to a Vector<String>
        
        @SuppressWarnings("unchecked")
        private static final Vector<String> data = (Vector<String>) LFEC.readObjectFromFile_JAR
            (DataFileLoader.class, "dataFile.sdat", true, Vector.class);
        
        Type Parameters:
        T - This type parameter is simply provided for convenience, to allow the user to specify the return class, without having to cast the object and suppress warnings, or catch exceptions.
        Parameters:
        f - The name of the file containing a serialized java.lang.Object to load
        zip - This should be TRUE if, when serialized, the Object was compressed too, and FALSE if compression was not used.
        returnClass - This java.lang.Class<E> should be used to indicate what the type of the java.lang.Object that has been written to the file named by input-parameter String f. When the object is read from disk and de-serialized, the type of the instance shall be checked against this class.

        FOR EXAMPLE: If a Vector containing String's were last written to data-file 'f', then invoking this method to retrieve that Vector<String> would require passing 'Vector.class' to this parameter.

        IMPORTANT: This method will halt program execution if after reading an instance from the data-file, the resulting class-name obtained from the instance that was read produces as class-name that is not equal to or, rather, does not inherit from the class passed to 'returnClass'. The logic, or purpose, to this check is to add a layer of data-file integrity check to this class LFEC (Load-File-Exception-Catch).
        Returns:
        A de-serialized java.lang.Object present in the data-file passed by-name through file-name parameter 'f', and cast to the type denoted by parameter returnClass.
        See Also:
        FileRW.readObjectFromFile(String, boolean), ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         try
         {
             Object ret = FileRW.readObjectFromFile(f, zip);
        
             if (! returnClass.isInstance(ret))
        
                 ERROR_EXIT(
                     "Serialized Object from file: " + f + "\n" +
                     "Using expected (" + (zip ? "zip-compression" : "no-compression") + ")\n" +
                     "Didn't have an object with class-name: [" + returnClass + "]\n" +
                     "but rather with class-name: [" + ret.getClass().getName() + "]"
                 );
        
             return returnClass.cast(ret);
         }
        
         catch (Throwable t)
         {
             ERROR_EXIT(
                 t,
                 "Exception reading Serialized Object from file: " + f + "\n" +
                 "With intended read class-name of: " + returnClass + "\n" +
                 "Using expected (" + (zip ? "zip-compression" : "no-compression") + ")\n"
             );
         }
        
         throw new UnreachableError(); // Should NOT be possible to reach this statement...
        
      • readObjectFromFile_JAR

        🡅     🗕  🗗  🗖
        public static <T> T readObjectFromFile_JAR​
                    (java.lang.Class<?> classLoaderClass,
                     java.lang.String f,
                     boolean zip,
                     java.lang.Class<T> returnClass)
        
        This loads a java.lang.Object from a data-file located in a JAR File.

        Serializable Containers:
        This method will load ONLY ONE java.lang.Object out of the data-file from inside the '.jar' File. If you wish to save multiple Object's to a data-file, the best way to achieve this is to put however many Serializable-Object's you have into a Java Serializable-Container (such as java.util.Vector), and then save that container as a Serialized-Object File.

        There will be (just a modicum) of effort needed to 'cast' an Object that has been retrieved from a Serialized-Object Data-File into a Java POJO. It is usually well worth since Data Read/Write Operations are tremendously simplified due to the work done for the Serializable inteface.

        Generic Erasure:
        Java's Generic Classes (where a Type-Parameter such as 'E' is used - as in java.util.Vector<E>) do not preserve the chosen-types at runtime. Instead, at Compile-Time, the Java-Compiler will often issue warnings and errors to flag things that it doesn't like.

        Whenever working with Java-Generics, it is most important to remember that the only purpose whatsoever behind using them at all are for the Compile-Time Warning & Error Messages that they provide. Once RunTime has started, the Java Run-Time Environment doesn't know anything about the Types in it's Generic-Classes.

        Raw-Types Warnings:
        On such Compiler-Warning that is often generated is the Raw-Types Warning. When attempting to cast a Raw-Type to it's 'specified-type' after de-serializing a Java Object, it will be necessary to use the @SuppressWarnings("unchecked") Annotation to read & de-serialize Java Generics from disk.

        This will be required regardless of "how sure you are" that the type being read is, indeed, the type to which it is being assigned.

        Example:
        // Use the following Java 'Annotation' (Suppress Warnings)
        // This will allow the programmer to cast the "Raw-Type" Vector, to a Vector<String>
        
        @SuppressWarnings("unchecked")
        private static final Vector<String> data = (Vector<String>) LFEC.readObjectFromFile_JAR
            (DataFileLoader.class, "dataFile.sdat", true, Vector.class);
        
        Type Parameters:
        T - This type parameter is simply provided for convenience, to allow the user to specify the return class, without having to cast the object and suppress warnings, or catch exceptions.
        Parameters:
        classLoaderClass - This contains the 'class' that will be used by Java's java.lang.Class.getResourceAsStream(...) method. Please see the comments at the top of this class-documentation page for a better explanation of how Java's class-loader uses a 'java.lang.Class<E>' object to find data-files (which java calls 'resources') inside of a jar-file.

        All that is really going on is that as classes are loaded by the class-loader from the file-system and from jar-files - the class-loader actually remembers which jar-file's and which directories inside the jar-files contained any/all class-definitions ('.class' files) that were loaded from jar files instead of the file-system.

        This parameter class 'c' points to a jar-file and directory combination that will contain the date-file named/identified by the next parameter String 'f'.

        NOTE: The symbols <?> appended to the (almost) 'raw-type' here, are only there to prevent the java-compiler from issuing warnings regarding the use of "Raw Types." This warning is, actually, only issued if the command-line option -Xlint:all option is used.
        f - The name of the file containing a serialized java.lang.Object to load
        zip - This should be TRUE if, when serialized, the Object was compressed too, and FALSE if compression was not used.
        returnClass - This java.lang.Class<E> should be used to indicate what the type of the java.lang.Object that has been written to the file named by input-parameter String f. When the object is read from disk and de-serialized, the type of the instance shall be checked against this class.

        FOR EXAMPLE: If a Vector containing String's were last written to data-file 'f', then invoking this method to retrieve that Vector<String> would require passing 'Vector.class' to this parameter.

        IMPORTANT: This method will halt program execution if after reading an instance from the data-file, the resulting class-name obtained from the instance that was read produces as class-name that is not equal to or, rather, does not inherit from the class passed to 'returnClass'. The logic, or purpose, to this check is to add a layer of data-file integrity check to this class LFEC (Load-File-Exception-Catch).
        Returns:
        a de-serialized java.lang.Object present in the data-file passed by-name through file-name parameter 'f', and cast to the type denoted by parameter 'returnClass'.
        See Also:
        ERROR_EXIT(Throwable, String)
        Code:
        Exact Method Body:
         // These are 'java.lang.AutoCloseable', and java handles them automatically
         // if there is an exception
        
         try (
             InputStream is = classLoaderClass.getResourceAsStream(f);
        
             // The user may or may not have asked for reading a *COMPRESSED* file
             ObjectInputStream ois = zip
                 ? new ObjectInputStream(new GZIPInputStream(is))
                 : new ObjectInputStream(is);
         )
         {
             Object ret = ois.readObject();
        
             if (! returnClass.isInstance(ret)) ERROR_EXIT(
                 "Serialized Object from jar-file loading-using class: " +
                 classLoaderClass.getCanonicalName() + "\n" +
                 "Looking for data-file named: " + f + "\n" +
                 "Using expected (" + (zip ? "zip-compression" : "no-compression") + ")\n" +
                 "Didn't have an object with class-name: [" + returnClass + "]\n" +
                 "but rather with class-name: [" + ret.getClass().getName() + "]"
             );
        
             return returnClass.cast(ret);
         }
        
         catch (Throwable t)
         {
             ERROR_EXIT(
                 t,
                 "Exception reading Serialized Object from jar-file, loading-using class: " +
                 classLoaderClass.getCanonicalName() + "\n" +
                 "Looking for data-file named: " + f + "\n" +
                 "And attempting to retrieve an object having class-name: " + returnClass + "\n" +
                 "Using expected (" + (zip ? "zip-compression" : "no-compression") + ")\n"
             );
        
             throw new UnreachableError(); // Should NOT be possible to reach this statement...
         }