Free eBook - The Java Workshop

5 (3 reviews total)
By David Cuartielles , Andreas Göransson , Eric Foster-Johnson
  • A new free eBook every day on the latest in tech
  • 30 permanently free eBooks from our core tech library
  1. 1. Getting Started
About this book
Java is a versatile, popular programming language used across a wide range of industries. Learning how to write effective Java code can take your career to the next level, and The Java Workshop will help you do just that. This book is designed to take the pain out of Java coding and teach you everything you need to know to be productive in building real-world software. The Workshop starts by showing you how to use classes, methods, and the built-in Collections API to manipulate data structures effortlessly. You’ll dive right into learning about object-oriented programming by creating classes and interfaces and making use of inheritance and polymorphism. After learning how to handle exceptions, you’ll study the modules, packages, and libraries that help you organize your code. As you progress, you’ll discover how to connect to external databases and web servers, work with regular expressions, and write unit tests to validate your code. You’ll also be introduced to functional programming and see how to implement it using lambda functions. By the end of this Workshop, you’ll be well-versed with key Java concepts and have the knowledge and confidence to tackle your own ambitious projects with Java.
Publication date:
October 2019
Publisher
Packt
Pages
606
ISBN
9781838986698

 

1. Getting Started

Overview

In this chapter, we will be covering the fundamentals of Java. You will first learn to write and compile your first "Hello World!" program—traditionally the first step to practicing any new language. We will then discuss the differences between the command-line interface (CLI) and Graphical User Interface (GUI), and the relative benefits of both. By the end of this chapter, you will understand the basic concepts behind variables, know how to hold data within them, and, even, how to comment on your own code.

 

Introduction

When learning how to program in almost any programming language, the first example you will typically test is called "hello world." It is the simplest application possible; the aim is to write the expression "hello world" to whatever user interface the programming environment offers. Executing this program will introduce you to the basics of writing code using the IntelliJ editor, utilizing different types of data to be printed to the user interface and adding comments to your code.

When writing your first program, you will also discover how Java's syntax is constructed and how it relates to other languages such as C or C++. Understanding the syntax is key to starting to read code. You will learn how to distinguish where commands and functions begin and end, how parameters are passed over between blocks of code, and how to leave comments that will help you when revisiting your software in the future.

This chapter covers the basics of writing and testing programs as a first step toward building all the code that you will find in this book.

 

Writing, Compiling, and Executing Your Hello World Program

In the preface, you saw how to install the IntelliJ development environment. While it is possible to write Java code with literally any text editor, we believe it is good to see how to create applications using state-of-the-art tools such as the aforementioned software package.

However, prior to guiding you step by step through getting your first program to run, we should take a look at the code that will become your first executable running on Java. The following code listing shows the program. Read through it, and we will later revise what each one of the parts is doing:

public class Main {
    public static void main (String[] args) {
        System.out.println("Hello World!"); 
    }
}

The first line is what we call a class definition. All programs in Java are called classes. A program might consist of several classes. Classes carry inside them everything they need to perform the task they were designed for. For a class to be executable in Java, it must contain a method called main. In this program, you can see how the Main class contains a method called main that will be printing the sentence "Hello World!" to the system's default output.

The code included in the class definition (public class Main) indicates that the class itself is public, which means that it will be accessible from other programs running on your computer. The same happens for the method definition (public static void main(String[] args)). There is, however, a series of other things that require our attention:

  • static signifies that there is nothing in the system instantiating the main method. Because of the way the Java Virtual Machine works, the main method needs to be static, or it will not be possible to execute it.
  • void indicates that the main method will not be returning anything to any code calling it. Methods could, in fact, send an answer to a piece of code executing it, as we will see later in the book.
  • main is the name of the method. You cannot assign this a different name, since it is the method that makes the program executable and needs to be named this way.
  • String[] args are the parameters of the main method. Parameters are passed as a list of strings. In other words, the program could take arguments from other parts within your computer and use them as data. In the particular case of the main method, these are strings that could be entered on the command-line interface (CLI) when calling the program.

Exercise 1: Creating Your Hello World Program in Java

IntelliJ provides you with a pre-made "hello world" template. Templates help you to get started faster with your code, as they provide the components you may need to speed up development. Templates can also be used for educational purposes; this is the case when it comes to testing "hello world."

For this first exercise, start with the editor. We will leave some options as they are by default. We will later see how to personalize some of the options to better suit our needs:

  1. Open IntelliJ and you will see a window giving you several options. Click on Create New Project. It should be the first option in the list:
    Figure 1.1: Creating a new project on IntelliJ IDE

    Figure 1.1: Creating a new project on IntelliJ IDE

  2. A new interface should appear. The default options here are meant for creating a Java program, so you just need to click Next:
    Figure 1.2: Creating a new Java project

    Figure 1.2: Creating a new Java project

  3. Check the box to create the project from a template. Click on Java Hello World and then click Next:
    Figure 1.3: Create a Java Hello World project from template

    Figure 1.3: Create a Java Hello World project from template

  4. Name the project chapter01. Then, click Finish:
    Figure 1.4: Create a Hello World Project

    Figure 1.4: Create a Hello World Project

  5. As we haven't chosen a folder to store the projects (intentionally), IntelliJ will offer you the possibility to create a default project folder inside your user space. Click OK:
    Figure 1.5: Default project folder option on IntelliJ IDE

    Figure 1.5: Default project folder option on IntelliJ IDE

  6. You will see a popup with tips on how to use the software. If you have never used a development environment of this type before, then this is a good way to get information about how it functions every time IntelliJ boots up. Choose your preferences and then click Close:
    Figure 1.6: Tip on how to use the IDE

    Figure 1.6: Tip on how to use the IDE

  7. IntelliJ reminds you regarding the possibility of using a special tab dedicated to learning more about the environment in relation to programming. Click Got It.
  8. The editor presents a menu bar, a code navigation bar, a project navigation area, and the actual editor where you can see the code we explained earlier. Now it is time to test it. Click on the Run button (this is the triangle on the right-hand side of the code navigation bar).
    Figure 1.7: Execute the program by clicking on the Run button

    Figure 1.7: Execute the program by clicking on the Run button

  9. When the program runs, a terminal window unfolds at the bottom of IntelliJ. Here, you can see how the software called your JVM, the program's outcome, and a line from the editor reading Process finished with exit code 0, which means that no errors occurred.
    Figure 1.8: JVM showing the output

Figure 1.8: JVM showing the output

Note

Since we took all the options by default for this example, you will see that our program is called Main.java. In the following chapter, we will see how to create programs that we then name ourselves.

Basic Syntax and Naming Conventions

The first thing you will have noticed in the hello world program, when it comes to syntax, is how we group the code into blocks marked within sets of curly braces—{ and }. The Main class contains the main method. In other words, main is nested inside Main. This is how classes are defined in Java – in principle, they contain all of the methods they are going to use.

Another aspect of the Java syntax is that capitalization matters. If a command is defined as Print, it differs from another command called print, and the compiler will identify them as different. Capitalization falls under a convention, an unwritten rule among programmers on how names should be formatted in Java. You will have noticed that the class is called HelloWorld. In Java, the convention establishes that methods, classes, variables, and so on should be named by joining words together using capitals as a way to mark the separation between words. In addition, the names of classes should start with capitals.

Note

When you are starting off, it is easy to get confused between syntax, which is rigid and must be respected for the compiler to function, and conventions, which are intended for developers to better understand how code is supposed to function.

To some extent, the Java compiler doesn't care about whitespace characters, but there is a convention about using them to make code more readable. The first code listing you saw (Figure 1.8) can be rewritten as shown in Example02.java that follows. It will have the exact same result once compiled and executed:

public class Main {
    public static void main(String[] args) { 
        System.out.println("Hello World!"); 
    }
}

The System.out.println("Hello World!") function call will print out the expected message on the CLI. The command is nested inside the main(String[] args) method definition, which is nested inside the class definition. You could add more blank spaces, but it will not affect the functionality of the program. This is part of the syntax of Java, but also of other programming languages such as C, C++, and Scala.

Also, note that "Hello World!" is a String, a type of data. The following section will explore what types of data can be sent as parameters to the System.out.println() method call.

Printing Out Different Data Types

In Java, it is common to define methods that have the capability to use different sets of parameters. For example, the System.out.println() method can print other types of data that are not just pieces of text. You could, as an example, try to print out a simple number and see the result. Example03.java adds a couple of lines to the code to showcase different types of data:

public class Main {
    public static void main(String[] args) { 
        System.out.println("This is text"); 
        System.out.println('A'); 
        System.out.println(53); 
        System.out.println(23.08f); 
        System.out.println(1.97); 
        System.out.println(true); 
    }
}

The previous example will print out four lines to the CLI, representing the different arguments given to the System.out.println() method. The outcome will look as follows:

This is text
A
53
23.08
1.97
true
Process finished with exit code 0

You see six different types of data in this result: some text, a character, an integer number, two different kinds of decimal numbers, and a truth statement. In the Java programming language, we define those types of data as String, char, int, float, double, and boolean, respectively. There is a lot more to learn about data types, but let's first introduce a new topic: variables. This will help to understand why data types are important.

Variables and Variable Types

Variables are human-readable names given to slots of your computer memory. Each one of those slots can store some data, such as a number, a piece of text, a password, or the value of the temperature outside. This kind of data is what we call a variable type. There are as many variable types as there are data types in our programming language. The type of data we are using defines the amount of memory allocated to store the data. A byte (which is made up of 8 bits) is smaller than an integer (which is made up of 32 bits). A string comprises several characters, hence making it bigger than an integer.

byte, int (short for integer), String, and char (short for character) are variable types. To make use of a variable, you need to define it for the compiler to understand that it needs it in order to allocate some space for storing data. The variable definition is done by first determining its type, followed by the variable's name, and then you can optionally initialize it with a certain value.

The following code listing shows how to define a couple of variables of different types:

// a counter
int counter = 0;
// a String
String errMsg = "You should press 'NEXT' to continue";
// a boolean
boolean isConnected = false;

This next exercise will take you through how to modify the code listing from Example03.java in order to print out the values coming from the variables.

Exercise 2: Printing Different Types of Data

In this exercise, we shall declare variables of different data types and print it as an output. To do so, perform the following steps:

  1. Open IntelliJ. If you didn't get to try the code listing from Example03.java, let's start by creating a new project using the HelloWorld template:
    Figure 1.9: Create a new Java project

    Figure 1.9: Create a new Java project

  2. Once you have reached the step where you have the code generated by the development environment, copy all of the code, erase it, and paste in the code from the Example03.java listing instead:
  3. Try out the code, and check that the outcome is what it should be, as explained in Printing Out Different Data Types.
  4. Start by declaring a new variable of the String type and initialize it:
    public class Main {
        public static void main(String[] args) { 
            String t = "This is text";
            System.out.println("This is text"); 
            System.out.println('A'); 
            System.out.println(53); 
            System.out.println(23.08f); 
            System.out.println(1.97); 
            System.out.println(true); 
        }
    }
  5. Next, substitute the text in the first System.out.println() command with the variable. As the variable is linked to the piece of memory containing the string, executing the program will give the same result:
    public class Main {
        public static void main(String[] args) { 
            String t = "This is a text";
            System.out.println(t); 
            System.out.println('A'); 
            System.out.println(53); 
            System.out.println(23.08f); 
            System.out.println(1.97); 
            System.out.println(true); 
        }
    }
  6. Continue by declaring a variable of the char type, another of the int type, one of the double type, and finally, one of the boolean type. Proceed to use the variable names instead of the values when printing out to the CLI:
    public class Main {
        public static void main(String[] args) { 
            String t = "This is a text";
            char c = 'A';
            int i = 53;
            float f = 23.08f;
            double d = 1.97;
            boolean b = true;
            System.out.println(t);
            System.out.println(c);
            System.out.println(i);
            System.out.println(f);
            System.out.println(d);
            System.out.println(b);
        }
    }

With this example, not only have you learned about different types of data and the variables that store this data, but also about how methods can handle more than one data type.

Note

Notice how the float type, when defined, requires the letter f to be appended after the number. This way, Java will be able to distinguish between these two types of decimal variables.

Primitive versus Reference Data Types

Some data types are built on top of others. For example, strings are made of sequences of characters, so, in a sense, without characters, there would be no strings. You could say that characters are more core to the language than strings are. Like characters, there are other data types that are used to define the properties of a programming language. These data types, fundamental for the construction of the language itself, are what we call primitive data types.

The following table describes some of the basic types of variables you will find in Java, along with their characteristics:

Figure 1.10: Basic types in Java

Figure 1.10: Basic types in Java

The eight primitive data types represent truth levels (boolean), integral numbers (byte, short, int, and long), floating point numbers (float and double), and characters (char). Exercise 2, Printing Different Types of Data showcased how to use variables from some of these types within our programs.

Note

String is not a primitive data type. It is what we call a reference data type. A mnemotechnic that could help you remember why it is called "reference" is that it is not linking to the actual data, but to the position in memory where the data is stored; hence, it is "a reference." There are other reference data types that you will be introduced to later in the book. Note that float and double are not precise enough to deal with some uses of decimal numbers, such as currencies. Java has a high-precision decimal data type called BigDecimal, but it is not a primitive type.

Null

In the same way that primitive data types have a default value, reference data types, which could be made of any kind of data, have a common way to express that they contain no data. As an example of a reference typed variable, the default value for a string that is defined as empty is null.

Null is a lot more complex than that, though—it can also be used to determine termination. Continuing with the example of the string, when stored in memory, it will be made of an array of characters ending with null. In this way, it will be possible to iterate within a string, since there is a common way to signify that you have reached its end.

It is possible to modify the content of the computer memory during the execution of a program. We do this using variables in code. The next code listing (Example04.java) will show you how to create an empty variable of the String type and modify its value while the program is running:

public class Main {
    public static void main(String[] args) { 
        String t = null;
        System.out.println(t); 
        t = "Joe ...";
        System.out.println(t); 
        t = "went fishing";
        System.out.println(t); 
    }
}

The previous example shows how to declare an empty string, how its value can be modified throughout the program, and how the program will cope with displaying the content of an empty string. It literally prints out the word null on the CLI. See the full outcome of the program:

null
Joe ...
went fishing
Process finished with exit code 0  

The program declares an empty variable, and by assigning new values to it, overwrites the variable's contents with new content.

Chars and Strings

As explained in Primitive versus Reference Data Types, strings are made of sequences of characters. A character is a symbol representing a letter in the alphabet, a digit, a human-readable symbol such as the exclamation mark, or even symbols invisible to the eye, such as the blank space, end-of-line, or tabulation characters. Strings are variables that refer to a part of the memory containing a one-dimensional array of characters.

Java allows the use of the mathematical composition of characters into strings. Let's take the previous example that printed the message "Joe . . . went fishing." Let's modify this in Example05.java so that it will add the different parts of the string together instead of overwriting the variable at each step:

public class Main {
    public static void main(String[] args) { 
        String t = null;
        System.out.println(t); 
        t = t + "Joe . . . ";
        System.out.println(t); 
        t = t + "Joe . . . went fishing";
        System.out.println(t); 
    }
}

The outcome for this program will be the following:

null
nullJoe ...
nullJoe ... went fishing
Process finished with exit code 0

What happens here is that the program prints the string as we make it grow longer by appending new parts to it. However, the result is a non-desired one (unless you really want the program to print null in front of the string).

Now it is time to see what happens when you do not declare a variable properly. Modify the previous code listing, and observe the outcome from the development environment.

Exercise 3: Declaring Strings

Modify the code example from Example05.java to see how the development environment will respond to the non-valid declaration of a variable. To do so, perform the following steps:

  1. Start by creating a program using the HelloWorld template and overwrite all of the code with the listing from the Example05.java file.
  2. Try the program. You should get the outcome presented earlier in this section.
  3. Modify the line where the string is declared to be as follows:
    String t;
  4. When executing the program, you will get an error as the result:
    Error:(4, 28) java: variable t might not have been initialized
  5. Declare the string to be empty, as in, containing no characters. You can do this by using the following line of code to declare the string:
    String t = "";

    After making this modification, the program's result will be as follows:

    Joe ...
    Joe … went fishing
    Process finished with exit code 0

Doing Some Math

You could say that the code presented in the Example05.java file's listing represents a way to add strings. This operation of adding strings is called concatenation. At the same time, it is possible to run all kinds of simple and complex mathematical operations using variables as part of the equation.

The basic mathematical operators in Java are addition (+), subtraction (-), multiplication (*), and division (/). An example of some operations being performed is presented here:

t = a + 5;
b = t * 6.23;
n = g / s - 45;

The order in which operations will be performed is that of normal math: multiplication and division first, followed by addition and subtraction. If nesting is needed, you could use braces:

h = (4 + t) / 2;
f = j * (e – 5 / 2);

There are other mathematical operators, such as square root (sqrt()), minimum (min()), and round up a number (round()). Calling to some of these more advanced operations will require calling the methods from the Math library within Java. Let's see some example code that will execute some mathematical operations to see how this works, later using this to try and solve a simple equation from trigonometry:

public class Main {
    public static void main(String[] args) {
        float f = 51.49f;
        System.out.println(f);
        int i = Math.round(f);
        System.out.println(i);
    }
}

In the preceding example, you declare a variable of the float type and print it. Next, you declare a variable of the int type and initialize it with the result of rounding the previous variable, which eliminates the fractional part of the number. You can see that round() is part of Java's Math library and therefore has to be called this way.

Math.round() and System.out.println() are examples of calls to methods that belong to the standard Java libraries Math and System, respectively. Java comes with a plethora of useful methods that will make your interaction with the software quick and easy. We will look at them later in the book.

Exercise 4: Solving a Simple Trigonometry Problem

The goal of this exercise is to solve the hypotenuse of a right triangle, given the lengths of the other two sides. Note that the formula for calculating the hypotenuse of a right-angled triangle is as follows: h2 = a2 + b2

Figure 1.11: A right angled triangle with sides as a and b and h as the hypotenuse

Figure 1.11: A right angled triangle with sides as a and b and h as the hypotenuse

To do this, perform the following steps:

  1. Take, once more, the HelloWorld template as a point of departure for the exercise, create the program, and then let's build a new program by modifying its contents.
  2. Declare the values to each one of the problem's variables. Initialize the one corresponding to the hypotenuse with 0. Make all the variables of the double type:
    double a = 3;
    double b = 4;
    double h = 0;
  3. Given that the addition of the squares of a and b equals the square of h, rewrite the equation as follows:
    h = Math.sqrt(a*a + b*b);

    The sqrt() method is used to obtain the square root of a number.

  4. Add the necessary code to print out the result:
    System.out.println(h);

    The expected outcome of this program should be the following:

    5.0
    Process finished with exit code 0
  5. Programming languages typically offer more than one way to solve a problem. In this particular case, you could solve the calculation of the square of the a and b variables by using the Math.pow() method. This will calculate the power of a base by an exponent that is given as a parameter:
    h = Math.sqrt(Math.pow(a,2) + Math.pow(b,2));

    The form of the final program, given all the modifications, is as follows:

    public class Main {
        public static void main(String[] args) {
            double a = 3;
            double b = 4;
            double h = 0;
            h = Math.sqrt(Math.pow(a,2) + Math.pow(b,2));
            System.out.println(h);
        }
    }

Comments Help You to Share Code

Until now, you have just been writing programs and testing them. But if you intend to be part of a large software project where you will collaborate with others in the making of an application, you will have to share your code with others. Sharing code is an important part of the work of the contemporary developer, and, in order to share code, you will have to annotate it so that others can understand why you decided to solve certain challenges the way you did in your code.

There are two ways to comment code in Java: inline comments, which are marked using a double-slash, //; and more extensive comments, typically used at the beginning of large blocks of code, which are marked with an opening tag comprising a slash and an asterisk, /*, and a closing tag comprising an asterisk and a slash, */.

The following example showcases how to add comments to the resulting program from the previous exercise:

public class Main {
    public static void main(String[] args) {
        double a = 3; // first side of the triangle
        double b = 4; // second side of the triangle
        double h = 0; // hypotenuse, init with value 0
        // equation to solve the hypotenuse
        h = Math.sqrt(Math.pow(a,2) + Math.pow(b,2));
        System.out.println(h); // print out the results
    }
}

In the previous example, we commented both the opening of the program and each one of the lines. The idea is to highlight different ways to comment code—inline, before a line, at the beginning of the code. You will notice some special things in the comments; for instance, the opening comment includes the author of the code (eventually, you will also include your contact information) as well as a copyright notice, letting people know to what extent they are allowed to reuse your code.

Note

Copyright notices for code depend on a specific company's policies most of the time, and vary for almost every project. Be careful when adding these to your code.

CLI versus GUI

In this book, we are going to be using the CLI as a way to test and deploy code. On the other hand, we will be writing the code using the IntelliJ development environment, which has a Graphical User Interface (GUI). We are intentionally avoiding making programs that will be using a GUI to interact with users. Java, in its current form, is mostly used as a service running on a server, and therefore the generation of GUIs is not the main goal behind the use of Java.

Up to this point, this book has invited you to run the code from the IntelliJ environment. The following exercise will help you to create a fully compiled application and run it from the CLI.

Exercise 5: Running the Code from the CLI

We will start from the creation of the HelloWorld example. We will compile it and then look for it from a terminal window. You have to remember which folder you created your program in, as we will be executing it from there. In this example, we called the folder chapter01. If you named it differently, you will have to remember to use the correct folder name when necessary in the code for this exercise:

  1. Click on the Build Project button (this is the hammer on the toolbar), and check that the system is not throwing any errors. If there are any, the console at the bottom of the window will open up, indicating the possible errors.
  2. Next, open the terminal within the editor, and you will see a button at the bottom of the environment's window. This will show a CLI starting at the location where the program was created. You can see the contents of the folder by typing the ls command:
    usr@localhost:~/IdeaProjects/chapter01$ ls
    chapter01.iml  out  src
  3. There will be two different folders and one file. We are interested in checking the folder named out. It is the one containing the compiled version of our program.
  4. Navigate to that folder by issuing the cd out command. This folder contains a single subfolder called production – enter it, as well as the subsequent chapter01 subfolder:
    usr@localhost:~/IdeaProjects/chapter01$ cd out
    usr@localhost:~/IdeaProjects/chapter01/out$ cd production
    usr@localhost:~/IdeaProjects/chapter01/out/production$ cd chapter01
    usr@localhost:~/IdeaProjects/chapter01/out/production/chapter01$ ls
    Main.class
  5. Once at the right folder, you will find a file called Main.class. This is the compiled version of your program. To execute it, you need to call the java Main command. You will see the program's outcome directly at the CLI:
    usr@localhost:~/IdeaProjects/chapter01/out/production/chapter01$ java Main
    Hello World!

Activity 1: Obtaining the Minimum of Two Numbers

Write a program that will check two numbers entered as variables and print out the message "The minimum of numbers: XX and YY is ZZ", where XX, YY, and ZZ represent the values of the two variables and the result of the operation, respectively. To do this, perform the following steps:

  1. Declare 3 double variables: a, b, and m. Initialize them with the values 3, 4 and 0 respectively.
  2. Create a String variable r, it should contain the output message to be printed.
  3. Use the min() method to obtain the minimum of the two numbers and store the value in m.
  4. Print the results.

    Note

    The solution for this activity can be found via this link.

 

Summary

This chapter introduced you to the use of the IntelliJ development environment, which is the basic tool that will be used throughout the book. Many of IntelliJ's features are common in other tools, along with the language used in menus and the overall programming interface.

You have seen some basic aspects of Java's syntax: how classes are defined, how code is nested inside curly braces, and how semicolons end each one of the commands. Comments help make the code more readable, both for others with whom you may collaborate and for yourself when reviewing your code in the future.

The primitive types offer a collection of possible variable types to be used in your programs to carry data, store the results of operations, and transfer information between different blocks of code.

All examples in this chapter are built from modifying an initial example that we used as a point of departure: "hello world"—that is, printing a string on the CLI. In later chapters, you will learn how to create your own classes from scratch, name them according to your needs, and store them in different folders. The next chapter will specifically cover statements in Java that control the flow of the programs.

KAY34

About the Authors
  • David Cuartielles

    David Cuartielles is a doctorate in interaction design and a postgraduate in telecommunications. He has a strong interest in building technology for humans, and that implies creating platforms and tools that help people to easily perform complex tasks. He is a co-founder of the Arduino platform and also lectures at the Malmo University. He teaches at different universities all over the world, and has spoken in the fields of technology, education, and free/open licensing models. As the CTO in education for Arduino, he advises governments about possible ways of creating new educational programs using state of the art technology (and not just Arduino).

    Browse publications by this author
  • Andreas Göransson

    Andreas Göransson is a software consultant focusing on Android application and platform development. He has several years of experience from teaching software development in different languages at the university in Malmö. In the past few years, he has been helping small start-ups an

    Browse publications by this author
  • Eric Foster-Johnson

    Eric Foster-Johnson is a veteran programmer who writes enterprise software in Java, Grails, and other JVM technologies. He is a consultant for ObjectPartners. He has authored and co-authored more than 20 books, including Red Hat RPM Guide, Teach Yourself Linux, and Perl Modules.

    Browse publications by this author
Latest Reviews (3 reviews total)
Your Workshop series is fantastic.
Service was great and prompt
5 * for the very good offers in terms of price and variety.
Recommended For You
The Python Workshop

Learn the fundamentals of clean, effective Python coding and build the practical skills to tackle your own software development or data science projects

By Andrew Bird and 4 more
The C++ Workshop

Learn to create high-performance, error-free programs by understanding the core principles and techniques behind programming in C++

By Dale Green and 2 more
Responsive Web Design with HTML5 and CSS - Third Edition

Harness the latest capabilities of HTML5 and CSS to create a single UI that works flawlessly on mobile phones, tablets, and desktops — plus everything in-between

By Ben Frain
The Complete Python Course [Video]

Master Python and OOP concepts and structure your programs like a professional

By Codestars By Rob Percival and 1 more