Tuesday, November 30, 2021

Java Application With User Input in Docker Container

In this tutorial you will see how to run a Java program that needs user input using Docker so the aim is to dockerize a Java application so that the Docker container is interactive.

1. Java program

We'll start by writing a Java program that uses Scanner to take input from console and checks whether the entered number is a prime number or not.

package org.netjs.prgrm;

import java.util.Scanner;

public class PrimeNumber {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("Please enter a number: ");
    int num = sc.nextInt();
    boolean isPrime = true;  
    for(int i = 2; i < num/2; i++) {
      if(num % i == 0) {
        isPrime = false;
        break;
      }
    }  
    if(isPrime)
      System.out.println(num + " is a prime number");
    else
      System.out.println(num + " is not a prime number");

    sc.close();
  }
}

2. Creating Dockerfile

FROM openjdk:12-alpine

COPY . /usr/src/myjavaapp

WORKDIR /usr/src/myjavaapp

RUN javac PrimeNumber.java -d bin

CMD ["java", "-cp", "bin", "org.netjs.prgrm.PrimeNumber"]

For detailed explanation of Dockerfile instructions please refer this post- Run Java Application in Docker Container

Note here that -d option is used with javac to set the destination directory for the class files. When the PrimeNumber.java is compiled the resultant .class file is stored in the bin directory (with in the WORKDIR /usr/src/myjavaapp) specified with the -d option.

Another thing to note here is that package is also specified in the Java file that is why fully qualified name is given in the CMD instruction when the program is executed.

3. Build image

Following command builds the image and names the image as java-app.

docker build -t java-app .

4. Run Docker Image

Once the Docker image is created successfully you can run it using the docker run command by providing the name of the image which you want to run. But remember that Docker container has to be interactive, running it simply using run command results in an error as you won't be able to provide input.

D:\NETJS\java-docker>docker run java-app

Please enter a number:
Exception in thread "main" java.util.NoSuchElementException
        at java.base/java.util.Scanner.throwFor(Scanner.java:937)
        at java.base/java.util.Scanner.next(Scanner.java:1594)
        at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
        at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
        at org.netjs.prgrm.PrimeNumber.main(PrimeNumber.java:10)

5. Making Docker container interactive

Docker run command can take the following two options to make it interactive.

-i or -interactive: Keep STDIN open even if not attached

-t, --tty: Allocate a pseudo-TTY

Using these options with the run command does the trick.

 
D:\NETJS\java-docker>docker run -it java-app

Please enter a number:
7
7 is a prime number

That's all for this topic Java Application With User Input in Docker Container. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Run Python Application in Docker Container

You may also like-

  1. AtomicInteger in Java With Examples
  2. Race Condition in Java Multi-Threading
  3. New Date And Time API in Java With Examples
  4. Pre-defined Functional Interfaces in Java
  5. Difference Between Encapsulation And Abstraction in Java
  6. How to Read File From The Last Line in Java
  7. Spring util-namespace Example For Wiring Collection
  8. Angular Route - Passing Static Data

Run Python Application in Docker Container

In this tutorial you will see how to run a HelloWorld Python program using Docker or how to dockerize your Python application to run it with in a Docker container.

Steps to run Python hello world program with Docker

  1. Lets start by creating a separate directory where we can put the Python file and DockerFile.
  2. Create a Python file helloworld.py with in this directory.

    helloworld.py

    class HelloWorld:
        # method
        def display(self):
            print("Hello World Python Program from Docker")
    #creating object
    obj = HelloWorld()
    #calling method
    obj.display()
    
  3. Create a file named Dockerfile with in the same directory. Follow the same name as given with 'D' capitalized and no extension. This is the file which defines the steps needed to create the image and run it.

    Steps for running any application in Docker is to create a Docker image and then create and start a container using that image. Dockerfile has the set of instructions to create the Docker image, each instruction in a Dockerfile creates a layer in the image.

    Dockerfile

    FROM python:3
    COPY . /src/pythonapp
    WORKDIR /src/pythonapp
    CMD ["python", "helloworld.py" ]
    

    Explanation for these steps is as given below-

    • Often, an image is based on another image, in our case initial step is to get Python. Note that Docker container runs in isolation as a stand-alone entity having the application code and the required dependencies to run the application. In order to run our code Python should be installed in the container. There already is a Python image hosted in Docker hub, path is https://hub.docker.com/_/python, that we can pull by giving the name of the image (python) and tag (which indicates Python version, which is 3 in our Dockerfile).
    • COPY instruction is used to copy files or directories from source path to the to the filesystem of the container at the destination path. In our Dockerfile files from the current directory (.) are copied to the path /src/pythonapp in the container.
    • The WORKDIR instruction sets the working directory
    • CMD is used to provide defaults for an executing container. One of the forms for providing CMD instructions is ["executable","param1","param2"]. This form is used in our Dockerfile where "python" is passed as executable and "helloworld.py" is passed as parameter making the command to be executed as python helloworld.py when the container is run.
  4. Build image


    To build an image from the Dockerfile command used is docker build. One of the option you can use with build command is -t which is used to pass a name for your docker image and optionally a tag in a name:tag format.

    Change directory to the path where Dockerfile is stored and run the following command.

    D:\NETJS\python-docker>docker build -t python-hello-world:1.0 .
    

    . means using the current directory as context

    Build command goes through the instructions in the Dockerfile one by one and executes them as you can notice from the screenshot given below. Three instructions out of 4 from the Dockerfile will be executed to create Docker image where as the fourth instruction which is a CMD instruction will be executed when container is run.

    [+] Building 115.6s (8/8) FINISHED
     => [internal] load build definition from Dockerfile                                                                                                         
     => => transferring dockerfile: 131B                                                                                                                         
     => [internal] load .dockerignore                                                                                                                            
     => => transferring context: 2B                                                                                                                              
     => [internal] load metadata for docker.io/library/python:3                                                                                                  
     => [internal] load build context                                                                                                                            
     => => transferring context: 357B                                                                                                                            
     => [1/3] FROM docker.io/library/python:3@sha256:f44726de10d15558e465238b02966a8f83971fd85a4c4b95c263704e6a6012e9                                            
     => => resolve docker.io/library/python:3@sha256:f44726de10d15558e465238b02966a8f83971fd85a4c4b95c263704e6a6012e9                                            
     => => sha256:f48ea80eae5a5683e2a734cf4697827339af3ced11e26d0ad58433ddf6fac24f 8.62kB / 8.62kB                                                               
     => => sha256:647acf3d48c2780e00cd27bb0984367415f270d78477ef9d5b238e6ebd5290da 54.93MB / 54.93MB                                                             
     => => sha256:b02967ef003473d9adc6e20868d9d66af85b0871919bcec92419f65c974aa8ce 5.15MB / 5.15MB                                                               
     => => sha256:e1ad2231829e42e6f095971b5d2dc143d97db2d0870571ba4d29ecd599db62cb 10.87MB / 10.87MB                                                             
     => => sha256:f44726de10d15558e465238b02966a8f83971fd85a4c4b95c263704e6a6012e9 2.60kB / 2.60kB                                                               
     => => sha256:9f4d271aecfec02809b04fa2367895c173cbf2ad03a9b94d7b385498a826d2ce 2.22kB / 2.22kB                                                               
     => => sha256:5576ce26bf1df68da60eeb5162dccde1b69f865d2815aba8b2d29e7181aeb62b 54.57MB / 54.57MB                                                             
     => => sha256:a66b7f31b095b7fa01d8ba10e600a192bab43a1311f50216cf6fa9a45d0f435e 196.50MB / 196.50MB                                                           
     => => sha256:05189b5b27621c90d2dc99c54b36bf5820bb377d96a9947cd1a81438eae46ddf 6.29MB / 6.29MB                                                               
     => => extracting sha256:647acf3d48c2780e00cd27bb0984367415f270d78477ef9d5b238e6ebd5290da                                                                    
     => => sha256:af08e8fda0d6cb4f0394e2d81bc7c3e00c44d04f28c79b195e3e20e53e9e29b8 19.11MB / 19.11MB                                                             
     => => extracting sha256:b02967ef003473d9adc6e20868d9d66af85b0871919bcec92419f65c974aa8ce                                                                    
     => => extracting sha256:e1ad2231829e42e6f095971b5d2dc143d97db2d0870571ba4d29ecd599db62cb                                                                    
     => => sha256:287d56f7527b558bbad5f0dd5f529eb1d161d549cd7634990b203ea1af123f23 233B / 233B                                                                   
     => => sha256:dc0580965fb6016fadf90963a71fdd042a099f6043e816155fb2388c2c78e6a7 2.35MB / 2.35MB                                                               
     => => extracting sha256:5576ce26bf1df68da60eeb5162dccde1b69f865d2815aba8b2d29e7181aeb62b                                                                    
     => => extracting sha256:a66b7f31b095b7fa01d8ba10e600a192bab43a1311f50216cf6fa9a45d0f435e                                                                    
     => => extracting sha256:05189b5b27621c90d2dc99c54b36bf5820bb377d96a9947cd1a81438eae46ddf                                                                    
     => => extracting sha256:af08e8fda0d6cb4f0394e2d81bc7c3e00c44d04f28c79b195e3e20e53e9e29b8                                                                    
     => => extracting sha256:287d56f7527b558bbad5f0dd5f529eb1d161d549cd7634990b203ea1af123f23                                                                    
     => => extracting sha256:dc0580965fb6016fadf90963a71fdd042a099f6043e816155fb2388c2c78e6a7                                                                    
     => [2/3] COPY . /src/pythonapp                                                                                                                              
     => [3/3] WORKDIR /src/pythonapp                                                                                                                             
     => exporting to image                                                                                                                                       
     => => exporting layers                                                                                                                                      
     => => writing image sha256:b84b09f7ce8fc351122d1df9e32f82f9b0aa5808a93123986f5921a61603c9e3                                                                 
     => => naming to docker.io/library/python-hello-world:1.0      
    
  5. Run Docker Image

    Once the Docker image is created successfully you can run it using the docker run command by providing the name of the image which you want to run. Note that a container is a runnable instance of an image so this process can also be described as creating and starting a container where command is run.

    D:\NETJS\python-docker>docker run python-hello-world:1.0
    
    Hello World Python Program from Docker   
    

    As you can see on running the image CMD instruction given in Dockerfile is executed and output is displayed.

That's all for this topic Run Python Application in Docker Container. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Run Java Application in Docker Container

You may also like-

  1. How to Install PostgreSQL on Windows
  2. Transaction Management in Java-JDBC
  3. Try-With-Resources in Java With Examples
  4. static Import in Java With Examples
  5. Private Methods in Java Interface
  6. How to Install Node.js and NPM in Windows
  7. Java String charAt() Method With Examples
  8. Spring Boot REST API CRUD Example With Spring Data JPA

Monday, November 29, 2021

Spring Integration With Quartz Scheduler

This post shows how you can integrate Spring with Quartz Scheduler which is a tool for scheduling jobs.


Using Quartz scheduler

Quartz uses Job, JobDetail and Trigger objects to realize scheduling of all kinds of jobs. Following are some of the main classes/interfaces in Quartz Scheduler API.

  • Scheduler- This is the main interface of a Quartz Scheduler. A Scheduler maintains a registry of JobDetails and Triggers. Once registered, the Scheduler is responsible for executing jobs when their associated triggers fire (when their scheduled time arrives).
  • Job- Job is an interface which is to be implemented by classes which represent a 'job' to be performed. Job interface has a single method execute(JobExecutionContext context) which is called by the Scheduler when a Trigger fires that is associated with the Job.
  • JobDetail- Quartz does not store an actual instance of a Job class, but instead allows you to define an instance of one, through the use of a JobDetail interface.
  • JobDataMap- This class holds state information for Job instances. JobDataMap instances are stored once when the Job is added to a scheduler.
  • Trigger- Triggers are the 'mechanism' by which Jobs are scheduled. Triggers have a TriggerKey associated with them, which should uniquely identify them within a single Scheduler.

Spring integration with Quartz

Spring framework offers classes that simplify the usage of Quartz within Spring-based applications.

  • QuartzJobBean class- This abstract class is a simple implementation of the Quartz Job interface. It also applies the passed-in job data map as bean property values.
  • JobDetailFactoryBean- A Spring FactoryBean for creating a Quartz JobDetail instance, supporting bean-style usage for JobDetail configuration.

For example- Suppose you have a class EmailService for sending mails then it can be given as a property in a Job class than extends QuartzJobBean. The JobDetail instance can be configured using JobDetailFactoryBean where the job can be defined as a property along with JobDataMap.

@Service
public class MailReminderJob extends QuartzJobBean {

 private EmailService emailService;
 public void setEmailService(EmailService emailService) {
  this.emailService = emailService;
 }
 @Override
 protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
 ..
 ..
<bean name="emailReminderJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
  <property name="jobClass" value="org.netjs.service.MailReminderJob"/>
  <property name="jobDataAsMap">
    <map>
      <entry key="emailService" value-ref="emailService"></entry>
    </map>
  </property>
</bean>

Using MethodInvokingJobDetailFactoryBean

If you just need to invoke a method on a specific object you can use the MethodInvokingJobDetailFactoryBean to do that.

<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
  <property name="targetObject" ref="exampleBusinessObject"/>
  <property name="targetMethod" value="doIt"/>
</bean>

The above configuration will result in the doIt method being called on the exampleBusinessObject bean.

Configuring triggers

By now you have job and job details, you also need to configure triggers for scheduling the jobs.

Spring integration with Quartz offers two Quartz FactoryBean implementations with convenient defaults-

  • CronTriggerFactoryBean- Using this factory bean you can provide a cron expression.
  • SimpleTriggerFactoryBean- Using this factory bean you can provide properties for job scheduling like start time, repeat interval, start delay.

An example configuration for SimpleTriggerFactoryBean and CronTriggerFactoryBean-

<bean id="simpleTrigger" class=
"org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">

    <property name="jobDetail" ref="jobDetail"/>
    <!-- 5 seconds -->
    <property name="startDelay" value="5000"/>
    <!-- repeat every 60 seconds -->
    <property name="repeatInterval" value="60000"/>
</bean>
<bean id="cronTrigger" class=
"org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="exampleJob"/>
    <!-- run every morning at 8 AM -->
    <property name="cronExpression" value="0 0 8 * * ?"/>
</bean>

Scheduling triggers

Triggers need to be scheduled. Spring offers a SchedulerFactoryBean that exposes triggers to be set as properties. SchedulerFactoryBean schedules the actual jobs with those triggers.

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
    <list>
      <ref bean="cronTrigger"/>
      <ref bean="simpleTrigger"/>
    </list>
  </property>
</bean>

That's all for this topic Spring Integration With Quartz Scheduler. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Job Scheduling Using TaskScheduler And @Scheduled Annotation
  2. Spring Thread Pooling Support Using TaskExecutor
  3. Spring MVC @RequestParam Annotation Example
  4. Spring Batch Processing With List of Objects in batchUpdate() Method
  5. Spring Component Scan Example

You may also like-

  1. Injecting Inner Bean in Spring
  2. Using p-namespace For Shorter XML configuration in Spring
  3. Spring depends-on Attribute
  4. @Conditional Annotation in Spring
  5. collect() Method And Collectors Class in Java Stream API
  6. Functional Interfaces in Java
  7. BigInteger in Java With Examples
  8. Apache Avro Format in Hadoop

Saturday, November 27, 2021

Spring @Async @EnableAsync Annotations - Asynchronous Method Support

In this post we’ll see Spring support for asynchronous method execution using @Async annotation and how to enable support for it using @EnableAsync if you are using Java configuration.

Spring @Async annotation

When a method is annotated with @Async annotation the invocation of that method will occur asynchronously. Which means the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor.

Spring asynchronous method invocation example

For asynchronous method execution using @Async annotation in Spring framework following tasks are required.

  1. Enable scheduling annotations
  2. Define a TaskExecutor that will execute the method as a submitted task. In the example ThreadPoolTaskExecutor implementation of the TaskExecutor is used.
  3. Write a method annotated with @Async annotation.

Enable scheduling annotations using @EnableAsync annotation

To enable support for @Async annotation add @EnableAsync to one of your @Configuration classes. Also define a TaskExecutor.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@EnableAsync
@ComponentScan(basePackages = "org.netjs.service")
public class AppConfig {
 @Bean
 public TaskExecutor threadPoolTaskExecutor() {
  ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
  ex.setCorePoolSize(4);
  ex.setMaxPoolSize(6);
  ex.setQueueCapacity(10);
  ex.initialize();
  return ex;
 }
}
In case of XML configuration you can configure it as following using the task name space.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/task/spring-task.xsd">
    <context:component-scan base-package="org.netjs.service" />
    
    <task:annotation-driven executor="taskExecutor" />
    <task:executor id="taskExecutor" pool-size="5" queue-capacity="10"/>
</beans>

Service with @Async annotated method

@Service
public class EmployeeService {
  @Async
  public CompletableFuture<Integer> getEmployeeCount(){
    int count = 0;
    Object obj = em.createQuery("SELECT COUNT(emp) FROM Employee emp").getSingleResult();
    if(obj instanceof Integer){
      count=(Integer)obj;
    }else if(obj instanceof Long){
      count=((Long)obj).intValue();
    }
    return CompletableFuture.completedFuture(count);
  }
}

Here we have a method that returns a value which has to be invoked asynchronously. Note that such methods are required to have a Future typed return value. @Async methods may not only declare a regular java.util.concurrent.Future return type but also Spring’s org.springframework.util.concurrent.ListenableFuture or, as of Spring 4.2, CompletableFuture in Java too.

You can also apply the @Async annotation to a void-returning method.

@Async
void doSomething() {
   // this will be executed asynchronously
}

Or to a method with argument(s)

@Async
void doSomething(String s) {
  // this will be executed asynchronously
}
To run the above example you can use the following code.
public class App {
  public static void main( String[] args ){
    AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    EmployeeService employeeService = context.getBean("employeeService", EmployeeService.class);
    CompletableFuture<Integer> cf = employeeService.getEmployeeCount();
    try {
      System.out.println("Count--" + cf.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    context.registerShutdownHook();
  }
}

If you are using XML Configuration not Java config then you may need to use ClassPathXmlApplicationContext in place of AbstractApplicationContext.

That's all for this topic Spring @Async @EnableAsync Annotations - Asynchronous Method Support. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Email Scheduling Example Using Quartz Scheduler
  2. Spring MVC Generate Response as JSON Example
  3. Difference Between @Controller And @RestController Annotations in Spring
  4. Spring Transaction Management JDBC Example Using @Transactional Annotation
  5. @Required Annotation in Spring Framework

You may also like-

  1. Spring Bean Life Cycle
  2. Bean Definition Inheritance in Spring
  3. Autowiring Using Annotations in Spring
  4. RunTime Injection Using Spring Expression Language (SpEL)
  5. Lambda Expressions in Java 8
  6. Just In Time Compiler (JIT) in Java
  7. Searching Within a String Using indexOf(), lastIndexOf() And contains() Methods
  8. Uber Mode in Hadoop

Friday, November 26, 2021

Literals in Java

Java literals are the fixed values assigned to a variable. A literal doesn’t require any computation and it is possible to assign a literal to a variable of a primitive type and also to a String even though String is not a primitive type in Java.

As example–

Short s = 100;
int num = 9000;
Boolean flag = true;

Literals in Java can be classified into four types–

  • Integer Literals
  • Floating-point Literals
  • Character and String Literals
  • Boolean literals

Integer Literals in Java

Literal assigned to a type byte, short, int or long is called an integer literal in Java. Make sure when you assign a literal value to a byte or short it is within the range of that particular type.

An integer literal is of type long if it ends with the letter L or l; otherwise it is of type int. It is recommended that you use the upper case letter L because the lower case letter l is hard to distinguish from the digit 1.

You will generally use a base 10 number i.e. decimal as an integer literal. But integer literals can be expressed by Binary (base two) and hexadecimal (base 16) number system also. Integer literals can be expressed by these number systems:

  • Decimal: Base 10, whose digits consists of the numbers 0 through 9; this is the number system you use every day.
  • Hexadecimal: Base 16, whose digits consist of the numbers 0 through 9 and the letters A through F.
  • Binary: Base 2, whose digits consists of the numbers 0 and 1 (you can create binary literals in Java SE 7 and later).

As example if you want to write 50 using hexadecimal–

int hNum = 0x32;
System.out.println("" + hNum);

Same way, if you want to use binary system to assign literal 50–

int bnum = 0b110010;
System.out.println("" + bnum);

Note - The prefix 0x indicates hexadecimal and 0b indicates binary.

Floating-point Literals in Java

Literal assigned to a type float or double is called floating-point literal in Java. A floating-point literal is of type float if it ends with the letter F or f; otherwise its type is double in that case it can end with the letter D or d but that is optional.

Floating-point literal can also be expressed using E or e (for scientific notation).

As example

double dNum1 = 156.7;
// same value as d1, but in scientific notation
double dNum2 = 1.567e2;
float fNum  = 34.8f;

Character and String Literals in Java

Literals of types char and String may contain any Unicode (UTF-16) characters. Always use 'single quotes' for char literals and "double quotes" for String literals. The Java programming language also supports a few special escape sequences for char and String literals: \b (backspace), \t (tab), \n (line feed), \f (form feed), \r (carriage return), \" (double quote), \' (single quote), and \\ (backslash).

As example if you want to assign single quote (‘) itself to a char variable you need escape sequence in that case.

char c ='\'';
System.out.println(c);

That will give as output.

Example of String literals

String s = "Hello";
String lines = "This is the first line.\n"+
        "This is the second line.\n"+
        "This is the third line.\n";

One thing to note here is that String is not a primitive type when you create a String literal a reference to an instance of String class is created.

Boolean literal in Java

Boolean literal can have only one of two values true and false. A Boolean literal can only be assigned to a variable of type boolean. It can also be used be used with conditions which evaluate to a boolean value.

As example

int num1 = 9;
int num2 = 7;
if(num1 > num2 == true){
 System.out.println(" num1 is greater than num2");
}

Here if condition num1 > num2 evaluates to either true or false. Though it can be expressed implicitly also (preferred)

int num1 = 9;
int num2 = 7;
if(num1 > num2){
 System.out.println(" num1 is greater than num2");
}

Here you can see with if only expression is used (num1 > num2) as it will evaluate to true or false anyway.

That's all for this topic Literals in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Java Variable Types With Examples
  2. Primitive Data Types in Java
  3. Type Casting in Java With Conversion Examples
  4. Object Creation Using new Operator in Java
  5. String in Java Tutorial

You may also like-

  1. Java Abstract Class and Abstract Method
  2. Why main Method static in Java
  3. static Block in Java
  4. ArrayList in Java With Examples
  5. How to Loop Through a Map in Java
  6. Java Exception Handling And Method Overriding
  7. Java ReentrantLock With Examples
  8. Is String Thread Safe in Java

Thursday, November 25, 2021

Run Java Application in Docker Container

In this tutorial you will see how to run a HelloWorld Java program using Docker or how to dockerize your Java application to run it with in a Docker container.

Steps to run Java hello world program with Docker

  1. We'll start by creating a directory where we can put the Java file and DockerFile.
  2. Create a Java file HelloWorld.java with in this directory.

    HelloWorld.java

    public class HelloWorld {
      public static void main(String[] args){
        System.out.print("Java program Hello world From Docker");
      }
    }
    
  3. Create a file named Dockerfile with in the same directory. Do use the exact name for the file with 'D' capitalized and no extension. This is the file which defines the steps needed to create the image and run it.

    Dockerfile is read from top to bottom and each instruction in a Dockerfile creates a layer in the image. When you change the Dockerfile and rebuild the image, only those layers which have changed are rebuilt.

    Dockerfile

    FROM openjdk:12-alpine
    
    COPY . /usr/src/myjavaapp
    
    WORKDIR /usr/src/myjavaapp
    
    RUN javac HelloWorld.java
    
    CMD ["java", "HelloWorld"]
    

    Explanation for these steps is as given below-

    • Docker container runs as a stand-alone container having the application code as well as other dependencies required to run the code. In order to run Java code with in the container JDK is also needed to provide both the build and runtime environment. Often, an image is based on another image and as explained our image is based on the Java image so that's what the first line does. There already is a Java image hosted in Docker hub, path is https://hub.docker.com/_/openjdk, that we can pull by giving the name of the image and tag (which includes Java version).
    • COPY instruction is used to copy files or directories from source path to the to the filesystem of the container at the destination path. In our Dockerfile, files from the current directory (.) are copied to the path /usr/src/myjavaapp in the container.
    • The WORKDIR instruction sets the working directory
    • The RUN instruction will execute any commands, in our case it compiles the Java file using the javac tool.
    • CMD is used to provide defaults for an executing container. One of the forms for providing CMD instructions is ["executable","param1","param2"]. This form is used in our Dockerfile where "java" is passed as executable and "HelloWorld" is passed as parameter making the command to be executed as java HelloWorld when the container is run.
  4. Build image

    docker build command is used to build an image from the Dockerfile. One of the option you can use with build command is -t which is used to pass a name for your docker image and optionally a tag in a name:tag format.

    Change directory to the path where Dockerfile is stored and run the following command.

    D:\NETJS\java-docker>docker build -t java-hello-world:1.0 .
    

    . means using the current directory as context

    Build command goes through the instructions in the Dockerfile one by one and executes them as you can notice from the screen shot given below 1/4, 2/4, 3/4 and 4/4 which means 1 out of 4 instructions, 2 out of 4 instructions and so on.

    D:\NETJS\java-docker>docker build -t java-hello-world:1.0 .
      
    => [internal] load build definition from Dockerfile                                                                                                         
     => => transferring dockerfile: 172B                                                                                                                         
     => [internal] load .dockerignore                                                                                                                            
     => => transferring context: 2B                                                                                                                              
     => [internal] load metadata for docker.io/library/openjdk:12-alpine                                                                                         
     => [internal] load build context                                                                                                                            
     => => transferring context: 355B                                                                                                                            
     => [1/4] FROM docker.io/library/openjdk:12-alpine@sha256:fecd532eaee349b4d9e329148e99de77ffaf803e66e184a0e4d6b946bb97ffa3                                   
     => => resolve docker.io/library/openjdk:12-alpine@sha256:fecd532eaee349b4d9e329148e99de77ffaf803e66e184a0e4d6b946bb97ffa3                                   
     => => sha256:fecd532eaee349b4d9e329148e99de77ffaf803e66e184a0e4d6b946bb97ffa3 433B / 433B                                                                   
     => => sha256:37b8b402893091d9120401a3d9c87d81a6fa967d96ca81e06a80d01605845c79 741B / 741B                                                                   
     => => sha256:0c68e7c5b7a0cb1612ea7b14c460d1f165ae7250b8aa7a0e5e53ae6cdc846310 3.44kB / 3.44kB                                                               
     => => sha256:6c40cc604d8e4c121adcb6b0bfe8bb038815c350980090e74aa5a6423f8f82c0 2.75MB / 2.75MB                                                               
     => => sha256:9716b977a99b5983f66063ce42eaa529af94f6265b6908558041581c3ae5b4ac 197.66MB / 197.66MB                                                           
     => => extracting sha256:6c40cc604d8e4c121adcb6b0bfe8bb038815c350980090e74aa5a6423f8f82c0                                                                    
     => => extracting sha256:9716b977a99b5983f66063ce42eaa529af94f6265b6908558041581c3ae5b4ac                                                                    
     => [2/4] COPY . /usr/src/myjavaapp                                                                                                                          
     => [3/4] WORKDIR /usr/src/myjavaapp                                                                                                                         
     => [4/4] RUN javac HelloWorld.java                                                                                                                          
     => exporting to image                                                                                                                                       
     => => exporting layers                                                                                                                                      
     => => writing image sha256:89ea194bd4b5fc9c571367caffc6e63279b05d68027e8b92a611b3389833dc80                                                                 
     => => naming to docker.io/library/java-hello-world:1.0     
    
  5. Run Docker Image

    Once the Docker image is created successfully you can run it using the docker run command by providing the name of the image which you want to run. Note that a container is a runnable instance of an image so this process can also be described as creating and starting a container where command is run.

    D:\NETJS\java-docker>docker run java-hello-world:1.0
    
    Java program Hello world From Docker
    
    As you can see on running the image CMD instruction given in Dockerfile is executed and output is displayed.

That's all for this topic Run Java Application in Docker Container. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Docker Tutorial: Introduction to Docker
  2. Java Application With User Input in Docker Container
  3. Run Python Application in Docker Container

You may also like-

  1. Angular Project Structure With File Description
  2. PostgreSQL - Create Database
  3. Var type in Java - Local Variable Type Inference
  4. Types of JDBC Drivers
  5. How to Resolve Local Variable Defined in an Enclosing Scope Must be Final or Effectively Final Error
  6. How to Create Immutable Class in Java
  7. Volatile Keyword in Java With Examples
  8. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example

Wednesday, November 24, 2021

Java Stream - findAny() With Examples

In Java Stream API findAny() method is used to return some element of the stream. Method returns the element as an Optional or an empty Optional if the stream is empty.

Syntax of the Stream.findAny() method is as follows-

Optional<T> findAny()

findAny() is a short-circuiting terminal operation meaning it may terminate in finite time when presented with infinite input.

The element of the Stream returned by findAny() is random in nature though in most of the case it returns the first element of the stream just like findFirst() method but this behavior is not guaranteed.

Java Stream findAny() examples

1. An example to get some element from a Stream of Integers.

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class StreamFindAny {

  public static void main(String[] args) {
    List<Integer> list = Arrays.asList(3, 9, 1, 9, 7, 8);
    Optional<Integer> anyNumFromStream = list.stream().findAny();
    if(anyNumFromStream.isPresent()) {
      System.out.println("Element in the Stream- " + anyNumFromStream.get());
    }else {
      System.out.println("No element found");
    }
  }
}

Output

Element in the Stream- 3

2. You can also use findAny() method along with other Stream operations to get any element from the resultant stream. For example using filter method to filter out elements which are less than 5 and then getting any element from the resultant stream.

public class StreamFindAny {

  public static void main(String[] args) {
    List<Integer> list = Arrays.asList(3, 2, 6, 2, 7, 8);
    list.stream()
      .filter(e -> e > 5)
      .findAny()
      .ifPresent(System.out::println);
  }
}

Output

6

That's all for this topic Java Stream - findAny() With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Java Stream - findFirst() With Examples
  2. Java Stream - max() With Examples
  3. collect() Method And Collectors Class in Java Stream API
  4. Java Stream - concat() With Examples
  5. Java Stream - count() With Examples

You may also like-

  1. Adding Tomcat Server to Eclipse
  2. JVM Run-Time Data Areas - Java Memory Allocation
  3. Types of JDBC Drivers
  4. Java ArrayBlockingQueue With Examples
  5. What Are JVM, JRE And JDK in Java
  6. How to Read Input From Console in Java
  7. Angular First App - Hello world Example
  8. Spring Component Scan to Automatically Discover Beans

Tuesday, November 23, 2021

Java Stream - findFirst() With Examples

In Java Stream API, findFirst() method is used to find the first element of this stream. Method returns the first element as an Optional or an empty Optional if the stream is empty.

Syntax of the Stream.findFirst() method is as follows-

Optional<T> findFirst()

findFirst() is a short-circuiting terminal operation meaning it may terminate in finite time when presented with infinite input.

Java Stream findFirst() examples

1. An example to get first element from a Stream of Integers.

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class StreamFindFirst {

  public static void main(String[] args) {
    List<Integer> list = Arrays.asList(3, 9, 1, 9, 7, 8);
    Optional<Integer> firstNumFromStream = list.stream().findFirst();
    if(firstNumFromStream.isPresent()) {
      System.out.println("First Element in the Stream- " + firstNumFromStream.get());
    }else {
      System.out.println("No element found");
    }
  }
}

Output

First Element in the Stream- 3

2. You can also use findFirst() method along with other Stream operations to get the first element from the resultant stream. For example using filter method to filter out elements which are less than 3 and then getting the first element from the resultant stream.

public class StreamFindFirst {

  public static void main(String[] args) {
    List<Integer> list = Arrays.asList(3, 9, 1, 9, 7, 8);
    Optional<Integer> firstNumFromStream = list.stream()
                           .filter(e -> e > 3)
                           .findFirst();
    if(firstNumFromStream.isPresent()) {
      System.out.println("First Element in the Stream- " + firstNumFromStream.get());
    }else {
      System.out.println("No element found");
    }
  }
}

Output

First Element in the Stream- 9

3. Using with Stream of strings. In the example findFirst() is used to get the first name that starts with “M”.

public class StreamFindFirst {

  public static void main(String[] args) {
    List<String> nameList = Arrays.asList("Andy", "Mona", "Vikram", "Jenny", "Meena");
    Optional<String> firstName = nameList.stream()
                           .filter(e -> e.startsWith("M"))
                           .findFirst();
    if(firstName.isPresent()) {
      System.out.println("First Element in the Stream- " + firstName.get());
    }else {
      System.out.println("No element found");
    }
  }
}

Output

First Element in the Stream- Mona

That's all for this topic Java Stream - findFirst() With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Java Stream - findAny() With Examples
  2. Java Stream - min() With Examples
  3. Java Stream - limit() With Examples
  4. Java Stream - boxed() With Examples
  5. Java Stream API Interview Questions And Answers

You may also like-

  1. forEach Statement in Java 8
  2. Java Lambda Expression as Method Parameter
  3. HashSet Vs LinkedHashSet Vs TreeSet in Java
  4. Multi-Catch Statement in Java Exception Handling
  5. Java Program to Reverse a Number
  6. Spring Bean Life Cycle
  7. Namespace And Variable Scope in Python
  8. Angular Pipes With Examples

Sunday, November 21, 2021

Multiple Catch Blocks in Java Exception Handling

There might be a case when a code enclosed with in a try block throws more than one exception. To handle these types of situations, multiple catch blocks can be specified where each catch clause catches a different type of exception. When an exception is thrown, every catch statement is inspected in order, and the first one whose type matches that of the thrown exception is executed.

After one of the catch statement, out of the multiple catch blocks, executes the others are bypassed and execution continues after the try-catch block.

Notice that with Java 7 and later it is possible to catch multiple exceptions in one catch block, which eliminates the duplicated code. Refer Multi catch statement in Java 7 to read more about it.

Multiple catch blocks Java example

In this program there is an array with only one element which is zero. From main method when calculateValue method is called a parameter is passed which is used as an index of the array.

First time 0 is passed which will mean divide by a[0]. Since the value at that index is 0 thus it will result in divide by 0 and ArithmeticException will be thrown.

Next time 2 is passed but array has only one element so trying to access a[2] will result in ArrayIndexOutOfBoundsException.

In the code there are multiple catch blocks and both of these exceptions will be caught by separate catch blocks.

public class MultipleCatchDemo {
  private void calculateValue(int i){
    int a[] = {0};
    try{
      int b = 7/a[i];
    }catch(ArithmeticException aExp){
      aExp.printStackTrace();
    }catch(ArrayIndexOutOfBoundsException aiExp){
      aiExp.printStackTrace();
    }
  }

  public static void main(String[] args) {
    MultipleCatchDemo mcDemo = new MultipleCatchDemo();
    mcDemo.calculateValue(0);
    mcDemo.calculateValue(2);
  }
}

Output

java.lang.ArithmeticException: / by zero
 at org.netjs.examples.impl.MultipleCatchDemo.calculateValue(MultipleCatchDemo.java:11)
 at org.netjs.examples.impl.MultipleCatchDemo.main(MultipleCatchDemo.java:21)
java.lang.ArrayIndexOutOfBoundsException: 2
 at org.netjs.examples.impl.MultipleCatchDemo.calculateValue(MultipleCatchDemo.java:11)
 at org.netjs.examples.impl.MultipleCatchDemo.main(MultipleCatchDemo.java:22)

Restriction with Multiple catch blocks in Java

When multiple catch blocks are used in Java, it is important to follow the order where the exception sub type is caught before any of their super type. Which means a catch block that catches an exception subclass must come before the catch clause that catches an exception super class.

As example– With in the Java exception handling hierarchy Exception class is super class and ArithmeticException is the child class so catch block for Exception class will catch an ArithmeticException too. Thus placing the catch block for Exception class before the catch block for ArithmeticException would mean that the catch block for ArithmeticException is never reached.

Note that in Java, unreachable code is an error so this situation will result in a compiler error.

In the same code as used above if one more catch block for Exception is added as the first one, that will result in compiler error.

multiple catch blocks

That's all for this topic Multiple Catch Blocks in Java Exception Handling. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Best Practices For Exception Handling in Java
  2. Creating Custom Exception Class in Java
  3. throws Keyword in Java Exception Handling
  4. Try-With-Resources in Java With Examples
  5. Java Exception Handling Interview Questions And Answers

You may also like-

  1. Difference Between Abstract Class And Interface in Java
  2. Inheritance in Java
  3. How to Loop Through a Map in Java
  4. Fail-Fast Vs Fail-Safe Iterator in Java
  5. Difference Between Thread And Process in Java
  6. Thread Priority in Java Multi-Threading
  7. Why wait(), notify() And notifyAll() Methods Are in Object Class And Not in Thread Class
  8. Varargs (Variable-length Arguments) in Java

Saturday, November 20, 2021

Object Creation Using new Operator in Java

In OOP a class provides the blueprint for objects; you create an object from a class. When a new class is created essentially a new data type is created. This type can be used to declare objects of that type. In this post we'll see what all happens when an object is created using new operator in Java.

Creating Objects in Java

Creation of an object for a class in Java is done in three steps-

  • Declaration- Declare a variable of the class type, note that no object is defined yet. This variable can refer to an object as and when the object is created.
  • Instantiation- Create an object and assign it to the variable created in step 1. This object creation is done using new operator.
  • Initialization- Class name followed by parenthesis after the new operator (new classname()) means calling the constructor of the class to initialize the object.

General form of using new operator by combining all these three steps is as-

Class_Name class_Variable = new Class_Name();

Here Class_Name is the class whose object is created and class_Variable is the variable that refers to the created object. Here note that when you refer Class_Name followed by parenthesis, you are actually calling the constructor of the class to initialize the object. That constructor may be a constructor with arguments or a no-argument constructor (or default constructor).

Let’s go through the steps of declaration, instantiation and initialization-

Declaring a Variable to Refer to an Object

When you just declare a variable no memory is allocated for it. As example if you declare a variable obj of class Test-

Test obj;

What you have done here is to notify the Java compiler that you will use obj to refer to data whose type is Test.

At this stage, when you have just declared the variable obj, it doesn’t refer to an object. Actually its value is undetermined at this time. To create an object you need to use the new operator in Java. You must assign an object to obj variable before you use it in your code. Otherwise, you will get a compiler error.

A variable in this state, which currently has no reference to any object can be pictorially represented as follows-

object declaration in Java
Object declaration

Instantiating a Java Class

The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. The new operator also invokes the object constructor.

The new operator requires a single, postfix argument: a call to a constructor and it returns the refrence to the object it created. This reference is usually assigned to a variable of the appropriate type, As example

Test obj = new Test(9, 10);

Initializing an Object in Java

The last step is to initialize an object. This is the process where constructor of the class is called to initialize the object.

As example-

If we have a Test class as follows-

public class Test{
  public int x = 0;
  public int y = 0;
  //constructor
  public Test(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

This class contains a single constructor which takes two integer arguments, in order to initialize a object created using new operator you can have a statement as follows-

Test obj = new Test(9, 10);

Here you have a variable obj of type Test, using new operator you have created a new object of class Test and initialized it to have values 9 and 10 for variables x and y respectively. So, this instantiation of class Test has its variables initialized to 9 and 10 i.e. obj.x = 9 and obj.y = 10.

obj is the variable that refers to the object.

If we have to pictorially represent this instantiation and initialization, it will look as follows.

Initializing an Object in Java
Initializing an Object

That's all for this topic Object Creation Using new Operator in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Package in Java
  2. Access Modifiers in Java - Public, Private, Protected and Default
  3. Abstraction in Java
  4. Difference Between Abstract Class And Interface in Java
  5. Core Java Basics Interview Questions And Answers

You may also like-

  1. Association, Aggregation and Composition in Java
  2. Initializer block in Java
  3. String in Java Tutorial
  4. Nested Try Statements in Java Exception Handling
  5. Generics in Java
  6. Map operation in Java Stream API
  7. How HashMap Works Internally in Java
  8. How ArrayList Works Internally in Java

Friday, November 19, 2021

Check if Given String or Number is a Palindrome Java Program

This post is about writing a Java program to find that a given string or number is a palindrome or not.

Remember a String or a number is a palindrome if it remains unchanged when reversed, for example "madam" is a palindrome as reverse of the madam is again madam. Another example is "malayalam" or 12344321.


Logic for finding if String palindrome or not

Here three ways are given to check whether given string is a palindrome or not in Java. First 2 ways use the inbuilt String functions to do that.

In the first method checkPalindrome1(), StringBuilder class instance is used which is instantiated using the given String, then the inbuilt reverse method of the StringBuilder is used. If the given string is a palindrome then reverse of the string should be same as the original string.

Second method checkPalindrome2() is same as the first method, it works on the logic that the second half of the string is the mirror image of the first half so if second half of the string is reversed then it should be same as the first half.
As example: If we have a string 12344321 then the second half 4321 if reversed will become 1234 which is equal to the first half, thus string is a palindrome.
In this logic whether a given string is of even length or odd length matters. That's why the ternary operator while creating the StringBuilder object.

index + index == str.length() ? str.substring(index) : str.substring(index + 1)

Third method checkPalindrome3() doesn't use any inbuilt function. In this method we start from the end of the string and read one character at a time to create a new String. Now if a given string is a palindrome then the new string should be equal to the original string.

Given String palindrome or not Java program

public class Palindrome {
  public static void main(String[] args) {
    Palindrome pm = new Palindrome();
    pm.checkPalindrome1("DogeeseseeGod");
    pm.checkPalindrome2("malayalam");
    pm.checkPalindrome3("1234442");
  }
    
  private void checkPalindrome1(String str){            
    StringBuilder sb = new StringBuilder(str);
    // reverse the string and check if it is equal to original 
    // string
    if(str.equalsIgnoreCase(sb.reverse().toString())){
      System.out.println(str + " is a Palindrome");
    }else{
      System.out.println(str + " is not a Palindrome");
    }        
  }
    
  /**
  * In a palindrome one half of the string is the mirror image of the other
  * this logic is based on that
  * @param str
  */
  private void checkPalindrome2(String str){        
    int index = str.length()/2;        
    StringBuilder sb = new StringBuilder(index + index == str.length() 
          ? str.substring(index) : str.substring(index + 1));
    if(str.substring(0, index).equalsIgnoreCase(sb.reverse().toString())){
      System.out.println(str + " is a Palindrome");
    }else{
      System.out.println(str + " is not a Palindrome");
    }        
  }        
    
  /**
  * If no inbuilt function has to be used.
  * 
  * @param str
  */
  private void checkPalindrome3(String str){
    StringBuilder sb = new StringBuilder();
    // start reading the string backward
    for(int i = str.length() - 1; i >= 0; i--){
      sb.append(str.charAt(i));
    }            
    System.out.println("string 3 " + sb.toString());
    if(str.equalsIgnoreCase(sb.toString())){
      System.out.println(str + " is a Palindrome");
    }else{
      System.out.println(str + " is not a Palindrome");
    }    
  }
}

Output

DogeeseseeGod is a Palindrome
malayalam is a Palindrome
string 3 2444321
1234442 is not a Palindrome

Java program to check if number palindrome or not

Though we can convert number to string and use any of the above mentioned methods to verify if given number is a palindrome or not but in a scenario where we have to do it for number this program can be used.

public class PalindromeNumber {

  public static void main(String[] args) {
    PalindromeNumber pm = new PalindromeNumber();
    pm.checkNumberPalindrome(12344321);
    pm.checkNumberPalindrome(12322);
  }
 
  /**
  * To check for integers
  * @param num
  */
  private void checkNumberPalindrome(int num){
    int reverse = 0;
    int remainder;
    int originalNum = num;
    // reversing the number
    while (num > 0) {
      remainder = num % 10;
      reverse = (reverse * 10) + remainder;
      num = num / 10;
    }
    if(reverse == originalNum){
      System.out.println(originalNum + " is a Palindrome");
    }else{
      System.out.println(originalNum + " is not a Palindrome");
    }
  }
}

Output

12344321 is a Palindrome
12322 is not a Palindrome

That's all for this topic Check if Given String or Number is a Palindrome Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. How to Find The Longest Palindrome in The Given String
  2. Check Given Strings Anagram or Not Java Program
  3. Count Number of Words in a String Java Program
  4. Add Double Quotes to a String Java Program
  5. Print Odd-Even Numbers Using Threads And wait-notify Java Program

You may also like-

  1. Find Largest and Second Largest Number in Given Array Java Program
  2. Method Overloading in Java
  3. Encapsulation in Java
  4. Race Condition in Java Multi-Threading
  5. Callable and Future in Java With Examples
  6. Java ReentrantLock With Examples
  7. How HashMap Works Internally in Java
  8. Dependency Injection in Spring Framework

Thursday, November 18, 2021

Spring Email Scheduling Example Using Quartz Scheduler

In this post we’ll see a Spring email scheduling example using Quartz scheduler integration with Spring framework.

Spring Mail API is used to configure Java mail for sending email.

Spring Quartz integration facilitates the use of Quartz for job scheduling.

Technologies Used

  • Spring 5.0.8.Release
  • Java 10
  • Java Mail API
  • Quartz Scheduler

Maven Dependencies

You need to add following dependencies for sending mail using Quartz scheduler in Spring framework.

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <spring.version>5.0.8.RELEASE</spring.version>
</properties>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>        
  </dependency> 
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
  </dependency>  
  <!-- Spring module Required for Quartz integration -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
     <groupId>com.sun.mail</groupId>
     <artifactId>javax.mail</artifactId>
     <version>1.6.1</version>
  </dependency>

  <dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.6.1</version>
  </dependency>
  <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
  </dependency>
  <dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
  </dependency>     
</dependencies>

Spring email scheduling example using Quartz scheduler

In this Spring email scheduling example reminder mail is sent to a set of Users everyday at the scheduled time. For scheduling the mail to be triggered at the specific time Quartz scheduler is used.

Bean class (User.java)

public class User {

  private String firstName;
  private String lastName;
  private String email;

  public User() {
   
  }
  public User(String firstName, String lastName, String email) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.email = email;
  }
  
  public String getFirstName() {
   return firstName;
  }
  public void setFirstName(String firstName) {
   this.firstName = firstName;
  }
  public String getLastName() {
   return lastName;
  }
  public void setLastName(String lastName) {
   this.lastName = lastName;
  }
  public String getEmail() {
   return email;
  }
  public void setEmail(String email) {
   this.email = email;
  }
}

Spring email scheduling example – Quartz Job class

Quartz scheduler job that would be called at the configured time. This class uses the EmailService class for sending the email. Here a dummy list of Users is created and EmailService method is called for each user in the list once the job is triggered.

@Service
public class MailReminderJob extends QuartzJobBean {
  private EmailService emailService;
  public void setEmailService(EmailService emailService) {
    this.emailService = emailService;
  }
  @Override
  protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    System.out.println("In executeInternal");
    List<User> userList = getListOfUsers();
    for(User user : userList) {
      emailService.sendMail(user);
    }
  }
    
  // Dummy method for adding List of Users
  private List<User> getListOfUsers() {
    List<User> users = new ArrayList<User>();
    users.add(new User("Jack", "Reacher", "jr@gmail.com"));
    users.add(new User("Remington", "Steele", "rs@gmail.com"));  
    return users;
  }
}

Spring email scheduling example – Mail Service class

Class used for sending the mails. This class get the mail properties like From and Subject from a properties file email.properties which is stored in the application’s classpath. MimeMessageHelper is used here so that attachment can also be sent with the email.

EmailService.java

@Service("emailService")
@Configuration
@PropertySource("classpath:email.properties")
public class EmailService {
 @Autowired
 private Environment env;
 @Autowired
 private JavaMailSender mailSender;

 public void sendMail(User user) {
  System.out.println("In Send mail");
  try{
   MimeMessage message = mailSender.createMimeMessage();
   // use the true flag to indicate you need a multipart message
   MimeMessageHelper helper = new MimeMessageHelper(message, true);
   helper.setFrom(env.getProperty("email.From"));
   // each user's email ID
   helper.setTo(user.getEmail());
   helper.setSubject(env.getProperty("email.Subject"));
   helper.setText("Dear " + user.getFirstName() + " " +user.getLastName()
   + "\r\n" + "This is a reminder mail to go through the attached PDF.");
   helper.addInline("Inline image", new ClassPathResource("netjs.png"));
   helper.addAttachment("MyImage.png", new ClassPathResource("netjs.png"));
   helper.addAttachment("MyPdf.pdf", new FileSystemResource("F:\\Doc\\index.pdf"));
  
   this.mailSender.send(message);
  }
  catch (MessagingException ex) {
   // just printing
   System.out.println(ex.getMessage());
  }
 }
}

email.properties

email.To=TO@gmail.com
email.From=FROM@gmail.com
email.Subject=Reminder Mail

Spring email scheduling example – Scheduling Configuration

The job is configured here to run at 8 AM everyday.

CronTrigger is used here for triggering the job using the implementation CronTriggerFactoryBean provided by the Spring framework for Quartz scheduling.

Trigger is scheduled using a SchedulerFactoryBean that exposes triggers to be set as properties.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
  <context:component-scan base-package="org.netjs.service" />
  <!-- Mail related configuration -->
  <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.gmail.com"/>
    <property name="port" value="587"/>
    <property name="username" value="GMAIL_USER_NAME"/>
    <property name="password" value="PASSWORD"/>
    <property name="javaMailProperties">
      <props>
        <prop key="mail.transport.protocol">smtp</prop>
        <prop key="mail.smtp.auth">true</prop>
        <prop key="mail.smtp.starttls.enable">true</prop>
        <prop key="mail.debug">true</prop>
      </props>
    </property>
  </bean>
  <!-- Quartz scheduler related configuration -->
  <bean name="emailReminderJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="org.netjs.service.MailReminderJob"/>
    <property name="jobDataAsMap">
      <map>
        <entry key="emailService" value-ref="emailService"></entry>
      </map>
    </property>
  </bean>

  <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="emailReminderJob"/>
    <!-- run every morning at 8 AM -->
    <property name="cronExpression" value="0 0 8 * * ?"/>
  </bean>
  <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
      <list>
        <ref bean="cronTrigger"/>
      </list>
    </property>
  </bean>
</beans>

To run this example you can use the following class.

public class App {
  public static void main( String[] args ){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");

  }
}

That's all for this topic Spring Email Scheduling Example Using Quartz Scheduler. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring MVC JSON as Response Example
  2. Spring Transaction Management Example - @Transactional Annotation and JDBC
  3. Spring Batch Processing Using JDBCTemplate batchUpdate() Method
  4. Spring Component Scan Example
  5. How to Read Properties File in Spring Framework

You may also like-

  1. Run Time Injection Using Spring Expression Language(SpEL)
  2. Excluding Bean From Autowiring in Spring
  3. BeanFactoryPostProcessor in Spring Framework
  4. Spring Web MVC Tutorial
  5. Difference Between Comparable and Comparator in Java
  6. How to Display Time in AM-PM Format in Java
  7. Java Collections Interview Questions And Answers
  8. Tips For Improving MapReduce Performance