Basic tools

Serialization

Make a serializable class Book that holds the following information:

The class BookStore stores books in a hash table, identifying them by their names. The class should implement the following methods:

// Initialises the hash map with some predefined data.
void addSomeBooks();

// Loads the books from the given file.
// Returns whether the loading was successful.
boolean loadBooks(String fileName);

// Saves the books into the given file.
// Returns whether the saving was successful.
boolean saveBooks(String fileName);

Make a command line application that tests the above operations.

Socket

Make a simple client-server application, whose parts communicate using TCP/IP. Use the classes Book and BookStore from the previous exercise.

The server accepts clients one after the other. When a client connects, the server does the following.

  1. Takes the name of a book from the client.
  2. Creates a BookStore.
  3. Tries to load the books from a file.
  4. Looks up the requested book by name in the store.
    1. If found, sends true to the client, then the book itself.
    2. Otherwise, sends false to the client.
  5. Saves the books to the file.

The client connects to the server, and takes the appropriate steps, mirroring the server.

  1. Connects to the server.
  2. Sends the name of the book.
  3. Processes the reply. To do that, first it reads a boolean value.

RPC

Make a server that communicates using TCP that serves the clients using a separate thread for each client.

  1. The client sends a string to the server.
  2. As reply, the server sends how many times it has received the same text before.

The server has to have an internal state, a data field of type java.util.HashMap<String, Integer>.

RMI

Make a server that is accessible through RMI through the interface BookService, which makes the following service available:

// Add a new book. If such a book is already present, return false, otherwise return true.
boolean add(Book newBook);

// If the book is present, return its title, otherwise, return null.
Book getByTitle(String title);

// Remove the book if present. Return whether the book was present.
boolean removeByTitle(String title);

Also make a client that accesses the server and tries its features.

You may use the following, simplified versions of Book and BookStore:

// Book.java ///////////////////////////////////////////////////////////////////

import java.io.Serializable;

public class Book implements Serializable {
  public String title;
  public String author;
  public int year;
  public int pages;
}
// BookStore.java //////////////////////////////////////////////////////////////

import java.util.HashMap;

public class BookStore {
  public HashMap<String, Book> books = new HashMap<>();

  public void BookStore() {
    for (int i = 0; i < 10; ++i) {
      Book book = new Book("Book #" + i, "Author #" + i, 2000 + i,
          300 + 10 * i);
      books.put(book.getTitle(), book);
    }
  }
}

Databases

Using Derby from the command line

  1. Start an Apache Derby database server instance using the command startNetworkServer.
  1. Connect to the Derby server using the command ij.
  1. First, create a database by executing
CONNECT 'jdbc:derby://localhost:1527/books;create=true';
  1. Create a table BOOK that stores books.
  1. Use SHOW TABLES and DESCRIBE BOOK to get more information.

  2. Use basic SQL operations (SELECT, INSERT, UPDATE, DELETE) to experiment with the database.

  3. You can stop the server with the stopNetworkServer command.

CONNECT 'jdbc:derby:books;create=true';

JDBC

Create an application that uses JDBC which persists the previous Book entities in a Derby database.

Implement a new BookStore class that uses the database:

// Constructor, connects to the database. In case of an error, prints an error message to the console.
BookStore(String host, int port);

// Adds a new book into the database. Returns true if there was no error, otherwise false.
boolean addBook(Book newBook);

// Deletes a book from the database. Returns true if there was no error, otherwise false.
boolean removeBookByTitle(String title);

// Gets all books from the database. In case of an error, returns the empty list.
java.util.List<Book> getAllBooks();

JPA

Database entity

Make a Book entity the following way:

Store the books in the database table books.

JPA

Make a class BookStore that handles the above Book entities via JPA. Implement the following operations:

// Constructor, gets the name of a persistence unit, and creates an appropriate `EntityManager` for it.
BookStore(String persistenceUnitName);

// Adds a new book into the database, and returns its identifier.
int addBook(Book newBook);

// Deletes the book with the given id (if it exists in the database).
void removeBookById(int bookId);

// Gets all books present in the database.
java.util.List<Book> getAllBooks();

Make a command line application that tests the BookStore class.

JPA relations

Create an entity Author that represents the author of a book:

Create a Book entity that contains the following data

// Adds an author.
Author addAuthor(String name, Date birthDate /* can be null */);

// Removes an author.
void removeAuthor(Author author);

// Adds a book with one author. It will be UNKNOWN in stock.
Book addBook(String title, Author author);

// Associates a book with an author.
void assignAuthorToBook(Author author, Book book);

// Removes a book.
void removeBook(Book book);

Enterprise Applications

Servlets

Make a web service that contains a servlet called ScopeTest. From the service’s root, the servlet should be accessible under /test.

The servlet has to do the following.

Try the application in various ways, and see what happens.

Web applications

  1. Here are the general steps on how you can create a web application in Eclipse.
  2. Make a new Dynamic Web Project.
  3. Right click on the project in Project Explorer, and choose Java EE Tools>Generate Deployment Descriptor Stub. This generates a web.xml file in WebContent/WEB-INF.
  4. If you are using JPA within GlassFish, you have to set that up as well.
    1. Go to the GlassFish Console: in your browser, go to the URL http://localhost:4848.
    2. Select Create New JDBC Resource, and create two resources for each of your persistence units: jdbc/YOURPERSISTENCEUNIT__pm and jdbc/YOURPERSISTENCEUNIT__nontx. (Note the double underscores.)
    3. Now, we are using Derby even more indirectly: we use JTA (Java Transaction API), which has to be indicated in META-INF/persistence.xml.
    4. Of course, Derby has to be running when you are deploying your application. See the bit about startNetworkServer in the environment setup guide.
  5. Note: if you encounter a problem while deploying your application (for example, sometimes you get the message Publishing to GlassFish ... has encountered a problem with the details cannot Deploy your-application-name deploy is failing=Application with name [your-application-name] is not deployed), you may have to explicitly remove it from GlassFish before you can attempt to deploy the application again. To do that, go to the Servers tab in Eclipse, select the application, and press Del.
  6. Basic setup is done, now you can create HTML files, servlets, JSP files, @WebMethods etc.
  7. Adding a JDBC resource in GlassFish, alternative way
  1. Open a console.
    1. Run $GLASSFISH/bin/asadmin start-domain
      • If your GlassFish application server is already running, you don’t need this step.
    2. Run $GLASSFISH/bin/asadmin create-jdbc-resource --connectionpoolid=DerbyPool RESOURCENAME
      • For the example, replace RESOURCENAME with jdbc/books__pm and jdbc/books__nontx (Note the double underscores.)
      • For your own projects, replace the jdbc/books parts above with your JTA data source, which is located in your project: JPA Content>persistence.xml, look inside the Source tab, see the jta-data-source element

Servlets, JSP

  1. Look at the provided example.
  2. Create a CompanyServlet that is available at /company-servlet from the root.
  1. Make a JSP page company.jsp which is used to store and display companies and their products.
  1. Change CompanyServlet to use JPA. Make two very simple entity types Company and Product; the servlet should provide functionalities to add a company and to add a product to a company. The servlet will always print the names of all companies with the names of their associated products.

EJB (Enterprise JavaBeans)

Stateless EJB

  1. Setup the application server (GlassFish). Click here for a description how.
  2. Look at the provided example.
  3. Here are the general steps on how to make a deployable application yourself.
  4. Make a project for the interface of the EJB. It will surely contain a Java interface for the EJB, but can also contain helper classes.
  5. Make an EJB project for the implementation of the EJB.
  6. Make an Enterprise Application Project that deploy the EJB.
  7. Make a client project, either with dependency injection, or with JNDI.
  8. Using the above description, make an application that has an EJB named Company with the interface CompanyInterface.
  1. In the EJB and its interface, write method hasProduct that takes a String and returns a boolean.
  2. Now, support product names in several languages the following way.

RESTful services: JAX-RS

  1. Look at the provided example.
  2. Make a @WebService with a @WebMethod named isBetween that takes three parameters. Let it return true iff param1 is between param2 and param3.
  1. Separate this functionality into three @WebMethods: setLowerBound, setUpperBound and isBetween. The implementing class will store the bounds, and isBetween only takes one number; it will check whether the parameter value is between the two stored values.
  1. Make such a RESTful service that can be used to store company names and the names of their products.

Additional exercises

Serialization

All classes/objects mentioned in this section are POJOs (Plain old Java objects).

  1. In the package example.company, create the classes Company and Person.
    1. Persons have a name and a job (strings), and an age. They also have an employer, a Company.
    2. Company objects have employees (a list of them), and they have a ceo (who is a Person).
  2. Create the following usual components in the above classes.
    1. toString
      • note: if you try to use the defaults, you’ll have a problem: you won’t be able to print all of the fields
    2. equals and hashCode
    3. getters and setters for the fields
      • for Company.employees, make and addEmployee, hasEmployee and removeEmployee
      • addEmployee, removeEmployee, setCompany should change the other side too (if it is not set already)
    4. a constructor that takes parameters similar to the fields
      • … except employees and employer
      • the company will start with one employee (the CEO)
        • remember: the CEO’s company has to be set to this company
  3. Create the class CompanyTester in the package example.company.test. This class will contain the main method. In main, let us maintain a list of Company objects.
    1. Create a method makeDefaults that will make some Company and Person objects, and associates them with each other.
  4. Make the Company and Person classes Serializable.
  1. In main, use makeDefaults to get some companies (with some employees).
  2. Save these companies into a file using ObjectOutputStream. (Their employees will be saved, too.)
  3. Load the companies from the file using ObjectInputStream. (Their employees will be loaded, too.)
  1. In the package example.company, create the classes Product. It will have an id (an int), and knows its producingCompany (a company) and buyer (an Employee).
  2. What do have to change if you want to use a Set instead of a List to store the employees of the company?

JPA

  1. Make an entity (File>New>JPA Entity) called TestEntity in the package test.entity, which is a simple class annotated with @Entity.
    1. Note that the class is listed in persistence.xml (under JPA Content in Project Explorer) in the Managed classes part. Also, have a look at the Source tab.
    2. Let it have an int field called id. It will be the entity’s primary key: annotate it with @Id. Also, add @GeneratedValue.
  2. Experiment with MyEntity instances: create some of them, persist them and query them.
  3. Experiment with persistence.xml settings, e.g. try to set eclipselink.ddl-generation to drop-and-create-tables instead of create-tables.
  4. Convert the Company, Person and Product classes from before to entities.
    1. First, only convert the fields with built-in types.
    2. You will have to add an id for each. Annotate them with @Id.