Featured resource
2025 Tech Upskilling Playbook
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Check it out
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Guided: Organize Java Code with Classes, Packages, and Access Modifiers

In this Code Lab, you will learn how to structure a Java application using packages, control access to your classes and their members with access modifiers, and compile and run a multi-file, multi-package application from the command line. You will build a simple library management system from the ground up, reinforcing core Java principles of encapsulation and modularity.

Lab platform
Lab Info
Level
Beginner
Last updated
Oct 23, 2025
Duration
45m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use.
Table of Contents
  1. Challenge

    Step 1: Creating the Data Model

    Every application needs a way to represent its data. In your library app, the most fundamental piece of data is a book. You will create a Book class to model this.

    To keep your code organized, you'll place this class inside a model package. The standard convention in Java is to use a reverse domain name for package names (e.g., com.mycompany.project.model). This ensures uniqueness and provides a clear structure. You will use com.library.model.

    Need Help? If you get stuck, reference the solution files in the solution directory. Each step has its own subdirectory (step1, step2, step3, step4) with complete solution files numbered sequentially (e.g., Book-1-1.java, Book-1-2.java) to show progression within each step. Next, you'll apply the principle of encapsulation. This means you'll hide the internal state (the fields) of your Book object from the outside world. You do this by declaring the fields as private. To allow controlled access, you'll provide public methods (getters) to read the data. This prevents other parts of your code from directly and perhaps incorrectly modifying the state of a Book object. --- This lab experience was developed by the Pluralsight team using Forge, an internally developed AI tool utilizing Gemini technology. All sections were verified by human experts for accuracy prior to publication. For issue reporting, please contact us.

  2. Challenge

    Step 2: Implementing the Repository Layer

    Now that you have a Book model, you need a way to store and retrieve them. This is the job of the Repository Layer. A repository acts as a collection of domain objects, abstracting away the details of how they are stored (in your case, a simple list; in a real app, it could be a database).

    You'll create a BookRepository class in its own repository package (com.library.repository) and use an import statement to make the Book class available. Here, you'll explore different access modifiers. You want the method that retrieves all books (findAll) to be available to any other class in the application, so you'll make it public. However, the method that initializes your sample data (init) is an internal helper. It should only be accessible to classes within the same package. For this, you use default access (achieved by not writing any access modifier). This prevents classes from outside the repository package from accidentally re-initializing your data.

  3. Challenge

    Step 3: Building the Service Layer

    The Service Layer sits between the application's entry point and the repository. Its role is to contain the business logic. For example, if you wanted to find only books by a certain author, the logic for that would go in the service layer.

    Your LibraryService will use the BookRepository to perform its tasks. It will hide the repository from the Main application class, providing a cleaner separation of concerns. You'll create it in a service package (com.library.service). The service class exposes the high-level operations your application can perform. By creating a public method listAvailableBooks(), you provide a simple, stable API for any client (like your Main class) to use, without needing to know any details about how or where the books are stored.

  4. Challenge

    Step 4: Assembling the Application

    Finally, you need an entry point to start your application. The Main class, containing the public static void main(String[] args) method, serves this purpose. It will be in the com.library package.

    This class is the 'client' of your service layer. It will create a LibraryService instance and use it to fetch and display the books, demonstrating how all the pieces you've built fit together.

  5. Challenge

    Step 5: Compiling and Running

    With all your classes written, the final step is to compile and run them. When working with packages, you can't just run javac *.java. You need to use specific flags to tell the compiler about your project structure.

    • javac -d <output_dir>: The -d flag specifies the directory where the compiled .class files should be placed. The compiler will automatically create the package directory structure inside this output directory.
    • -sourcepath <source_dir>: This tells the compiler where to find the .java source files.

    You will compile all your files into a bin directory. To run the compiled code, you use the java command. You need to tell the Java Virtual Machine (JVM) where to find your compiled classes using the classpath flag.

    • java -cp <classpath> or java -classpath <classpath>: This flag sets the path where the JVM will look for classes. Since you compiled everything into the bin directory, that will be your classpath.
    • com.library.Main: After the classpath, you provide the fully qualified name of the class that contains the main method you want to execute. ### Congratulations! You've successfully built a structured Java library application! These core concepts are essential for professional Java development.
About the author

Pluralsight Code Labs offer an opportunity to get hands-on learning in real-time. Be it a Challenge, Sandbox, or Guided Lab, these provide the real world experience needed to succeed in your development role.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight