Monday, August 28, 2023

Caused by java.io.IOException: CreateProcess error=206, The filename or extension is too long

While working on Java gradle project sometimes we might get the following error in Windows system:

Caused by: java.io.IOException: CreateProcess error=206, The filename or extension is too long

This is due to when classpath for a Gradle JavaExec or Test task is long, Windows command executions give error because of limitation to command line length greater than 32K

With a number of classpath dependencies in a large project, typically JavaExec Gradle task fails with error "The filename or extension is too long" and this would be a stopping error. To solve this issue, we can use the following gradle plugin. Use the plugin inside build.gradle file

apply plugin: "com.virgo47.ClasspathJar"

Or we can use inside build.gradle file under buildscript {} >> dependencies {} section as below:

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.com.virgo47.gradle:ClasspathJar:1.0.0"
  }
}

For Kotlin project, use it inside build.gradle.kts file as below:

apply(plugin = "com.virgo47.ClasspathJar")

Or we can use it in the build.gradle.kts kotlin file under buildscript {} >> dependencies {}

buildscript {
  repositories {
    maven {
      url = uri("https://plugins.gradle.org/m2/")
    }
  }
  dependencies {
    classpath("gradle.plugin.com.virgo47.gradle:ClasspathJar:1.0.0")
  }
}

ClasspathJar plugin creates a classpath jar for jar files in the classpath and sets the classpath with classpath jar. This includes JavaExec, Test and other similar tasks.

Build the application and run it.

Reference: ClasspathJar

Share:

Tuesday, August 23, 2022

How to setup auto renewable free SSL certificate using Lets Encrypt and Nginx on Ubuntu machine

In this tutorial, we are going to set up free SSL auto-renewable Let's Encrypt along with Nginx.

Prerequisites:

Before we start setup, first make sure your domain e.g example.com is pointed to the server's public IP address. You can set up and point this configuration from the dashboard of your domain service provider.

Connect to the remote server:

First SSH into the remote server where we want to set up the SSL.

If you are using a server password to connect, use the following command

sudo ssh server_username@ip_address

Here use your server username and server IP address to connect. For example ubuntu@34.344.56

If you are using a .pem file or other private keys to connect to a server then use the following command

sudo ssh -i path_to_pem_file server_username@ip_address

Install Nginx:

First, let's install Nginx on the server using the following commands.

sudo apt-get update
sudo apt-get install nginx

If nginx got successfully installed, then use the following command to verify.

nginx -v
nginx version: nginx/1.18.0 (Ubuntu)

Or we can verify by checking the status

sudo systemctl status nginx

Setup Nginx Configuration:

Now let's configure the Nginx for our domain. For this navigate to the Nginx directory

cd /etc/nginx/sites-available

Here, if we use the ls command we can see the default file for configuration. We will create a new file for our domain to configure for e.g 360learntocode.com, you can create using your domain name.

sudo vim 360learntocode.com

Now the new empty file is open lets edit and inserts the configuration by entering Shift + i

server {
      server_name 360learntocode.com;

      location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass              http://568.19.34.63:8080;
      }
}

Make sure to replace 360learntocode.com with your domain name and http://568.19.34.63:8080 with your IP address and the port in which your application is running.

Now save the configuration. Enter Esc and type :wq and hit Enter.

Now, symlink this file with the directory “sites-available” in our Nginx for this navigate to sites-available

cd /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/360learntocode.com /etc/nginx/sites-enabled/

To check the Nginx configuration use the following command

sudo nginx -t

We are supposed to see the output as below

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload the Nginx to reflect the changes:

sudo systemctl reload nginx

If we try to open our domain, we can see the Nginx 502 Bad Gateway if our application is not running otherwise we will see the running application.

Setup SSL Certificate:

For the SSL certificate, we are using the let's encrypt and certbot client. For more detail check let's Encrypt and Certbot

- Install Certbot client

Use the following commands to install certbot client

sudo apt-get update
 sudo apt-get install python3-certbot-nginx

Now, the certbot is successfully installed on our server. Let's create an SSL certificate for our domain

sudo certbot --nginx -d 360learntocode.com

Note: use your own domain name. Follow the steps asked afterward.

Here are some sample examples screens.

Now, let's reload the Nginx so that our configuration changes will reflect.

sudo systemctl reload nginx

If we load our domain URL then it will open over HTTPS.

If you want to see the overall configuration setup, please open the file that we created previously i.e 360learntocode.com inside /etc/nginx/sites-available/, there we can see all the setup done. The sample file looks like as below.

server {
      server_name 360learntocode.com;

      location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass              http://568.19.34.63:8080;
      }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/360learntocode.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/360learntocode.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = 360learntocode.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


      server_name 360learntocode.com;
    listen 80;
    return 404; # managed by Certbot


}

Here, the auto-renew script is managed by certbot client so we don't have to worry about the SSL expiration. To verify the auto-renew scripts navigate to the script file.

cd /etc/cron.d/
sudo vi certbot

In the certbot file, we can see the auto-renew script as below added by cerbot client

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

Thanks for following the tutorial, Happy coding !!

Share:

Mail Sending Issue in Java Application

Sometimes while sending the mail in the java application we might get the following issue.

org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 465; timeout -1;
  nested exception is:
	java.net.ConnectException: Connection timed out (Connection timed out). Failed messages: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 465; timeout -1;
  nested exception is:
	java.net.ConnectException: Connection timed out (Connection timed out)
	at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:432)
	at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
	at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
	at org.springframework.mail.javamail.JavaMailSender$send$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at grails.plugins.mail.MailMessageBuilder.sendMessage(MailMessageBuilder.groovy:130)
	Caused by: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 465; timeout -1
Caused by: java.net.ConnectException: Connection timed out (Connection timed out)

This might be due to a different reason.

Due to Firewall setup:

While sending mail we are using ports like 465 or 587 or other ports. So if you enable the firewall rules on your server then we might get this issue. So, enable the firewall rules for those TCP ports for outbound in your firewall settings.

The service provider disabled the port:

For security reasons, some server service providers disable those ports. For e.g:

For this, contact the service provider to allow the port or change the port on your configuration for your application. In the java application, for Gmail smtp.gmail.com we can use 587 instead of 465. The SMTP configuration looks as below:

["mail.smtp.host"           : "smtp.gmail.com",
				 "mail.smtp.starttls.enable": "true",
				 "mail.smtp.auth"           : "true",
				 "mail.smtp.port"           : "587",
		]
Share:

Tuesday, August 16, 2022

Convert Date to Pretty Time in Grails and Groovy

In this tutorial, we will learn how to convert Java Date to pretty time like moments ago, 1 hour ago, 1 week ago, 1 month ago, 1 year ago, and so on in grails application.

For this, we are using the prettytime plugin in our project.

Load PrettyTime in Grails Gradle project:

Add the following inside dependencies in the build.gradle file.

dependencies {
//other dependencies
 
compile 'org.grails.plugins:grails-pretty-time:4.0.0'
}

PrettyTime format Date:

Now let's create a method that formats the Java Date

import org.ocpsoft.prettytime.PrettyTime
import java.util.Date
public static String formatPrettyTime(Date date) {
        PrettyTime p = new PrettyTime()
        return p.format(date).trim()
    }

This will format the given date to a pretty time like moments ago.

Pretty Time Support Locale:

Prettytime support different language, for this use request to get the current locale and format it.

public static String formatPrettyTime(Date date, request) {
        Locale locale = RequestContextUtils.getLocale(request)
        PrettyTime prettyTime = new PrettyTime(locale)
        return prettyTime.format(date).trim()
    }

Here, we are using the locale from the request which gives the session locale for the current user

Current locale in grails application can also be achieved using LocaleContextHolder

import org.springframework.context.i18n.LocaleContextHolder
Locale locale = LocaleContextHolder.getLocale()

For pretty time supported language please follow prettyTime

Use in Gsp page:

If we are using the GSP pages HTML as server-side rendering, then we can use pretty time in GSP pages as below

<prettytime:display date="${someDate}" />
Share:

Monday, August 15, 2022

Convert Java Date to Pretty Time in Java

In this tutorial, we will learn how to convert Java Date to pretty time like moments ago, 1 hour ago, 1 week ago, 1 month ago, 1 year ago, and so on.

For this, we are using the prettytime dependency in our project.

If we are using a jar file download the desired jar file from the maven repository and load the jar file in the application. Please follow How to add external jar or library on IntelliJ IDEA project

Loading PrettyTime in Gradle Project:

Add the following inside dependencies in the build.gradle file.

dependencies {
//other dependencies
 
implementation 'org.ocpsoft.prettytime:prettytime:5.0.3.Final'
}

Loading PrettyTime in Maven Project:

Add the following dependency inside the pom.xml file.

<dependency>
  <groupId>org.ocpsoft.prettytime</groupId>
  <artifactId>prettytime</artifactId>
  <version>5.0.3.Final</version>
  <type>bundle</type>
</dependency>

Pretty Time format Date:

Now let's create a sample java class PrettyDateTime.java and create a converter method.

import org.ocpsoft.prettytime.PrettyTime;

import java.util.Date;

public class PrettyDateTime {

    public static void main(String[] args) {
        Date dateToConvert = new Date();
        System.out.println(convert(dateToConvert));
    }

    private static String convert(Date date) {
        PrettyTime p = new PrettyTime();
        return p.format(date);
    }
}

Here, we are creating the method convert which will convert the given Java Date to pretty time e.g moments ago.

Pretty Time format LocalDateTime:

import org.ocpsoft.prettytime.PrettyTime;

import java.time.LocalDateTime;

public class PrettyDateTime {

    public static void main(String[] args) {
        System.out.println(convert(LocalDateTime.now().minusSeconds(864000)));
    }

    private static String convert(LocalDateTime date) {
        PrettyTime p = new PrettyTime();
        return p.format(date);
    }
}

Pretty Time format in multiple languages:

Pretty time supports i18n and multiple languages.

import org.ocpsoft.prettytime.PrettyTime;

import java.util.Date;
import java.util.Locale;

public class PrettyDateTime {

    public static void main(String[] args) {
        Date dateToConvert = new Date();
        System.out.println(convert(dateToConvert, new Locale("de")));
    }

    private static String convert(Date date, Locale locale) {
        PrettyTime p = new PrettyTime(locale);
        return p.format(date);
    }
}

Here, we are using german support with "de" locale. For available language support follow prettyTime

Share:

Thursday, August 11, 2022

Java format date string to date and vice versa

This is a quick tutorial on formatting date in the string to java Date and Date to a date in string.

Let's create a sample java class called DateTimeUtils.java.

Parse Date String to Date:

Let's look into the example that we want to parse the date string 2022-08-22 or 2022-08-22 04:22:100 to Date.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTimeUtils {

    public static void main(String[] args) throws ParseException {
        String format = "yyyy-MM-dd HH:mm:ss";
        String dateToFormat = "2022-08-22 04:22:100";
        Date formattedDate = parseDate(dateToFormat, format);
        System.out.println(formattedDate);
    }

    static Date parseDate(String date, String format) throws ParseException {
        if (date.isEmpty()) return null;
        return new SimpleDateFormat(format).parse(date);
    }
}

Here, we are using the SimpleDateFormat java class for parsing the date string to Date. We can provide any valid format as needed instead of yyyy-MM-dd HH:mm:ss For e.g if we want to format "2022-08-22" to Date then we need to use the format "yyyy-MM-dd"

Parse Date to Date in String:

Now let's look into another example where we want to parse the date into the date string. Here we are trying to parse the current date to the desired format like "yyyy-MM-dd HH:mm:ss"

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTimeUtils {

    public static void main(String[] args) throws ParseException {
        String format = "yyyy-MM-dd HH:mm:ss";
        Date dateToFormat = new Date();
        String formattedDate = formatDate(dateToFormat, format);
        System.out.println(formattedDate);
    }

    static String formatDate(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }
}

We are using SimpleDateFormat class to format the desired Date to date in string

The format will be the desired valid format that might be "yyyy-MM-dd" as well.

Share:

Friday, July 29, 2022

How to grant privileges Mysql user for remote host machine

In this tutorial, we will learn how to grant privileges MySQL users for remote host/ip_address of the machine

SSH into remote server:

First, let's enter the remote server where the MySQL server is allocated.

ssh server_user_name@server_ip_address

Use your own server_user_name and server_ip_address.

ssh ubuntu@65.110.98.71

Now, logged in as MySQL's root user

mysql -u root_username -p

Enter your root username and hit enter. After that, it will ask for MySQL password use your MySQL password

Grant All Privileges for all host:

GRANT ALL PRIVILEGES ON *.* TO 'mysql_username'@'%' IDENTIFIED BY 'mysql_password';
FLUSH PRIVILEGES;

Here, we are giving the MySQL user access to it from any host or IP address by specifying %. Don't forget to flush privileges after granting privileges to the user.

Grant All Privileges for a host:

If we want to restrict MySQL user from all the hosts and give access to the specific IP address or host machine then we can use the following command

GRANT ALL PRIVILEGES ON *.* TO 'mysql_username'@'ip_address' IDENTIFIED BY 'mysql_password';
FLUSH PRIVILEGES;

Make sure to use your own mysql_username and ip_address to allow access from that host.

Revoke privileges:

REVOKE ALL PRIVILEGES ON *.* FROM 'mysql_username'@'ip_address';
FLUSH PRIVILEGES;

List host users:

SELECT user, host FROM mysql.user;

This will list all the users associated with the hosts.

List all the privileges given to users:

SELECT * FROM information_schema.user_privileges;

This will show all the users with hosts and privileges available for that user and host.

Delete user associated with host:

DROP USER 'mysql_username'@'ip_address';

This will drop the user associated with that IP address and revoke all the privileges.

Share:

Wednesday, July 27, 2022

Install Mysql in Docker on Ubuntu Linux server

In this tutorial, we will learn how to install Mysql on Docker.

Please follow the steps to install docker using this tutorial Install Docker on Ubuntu

Install Mysql using Docker:

For installing the desired version of MySQL first, visit docker mysql image section where we can find the available MySQL version. In this tutorial, we are using MySQL version 5.7.

Use the following command on the server to install the MySQL image

docker pull mysql:5.7 

Use your own version instead of 5.7

This will pull the image and install Mysql inside docker. We can verify the image using the following command

docker images

The output of the above command will be similar to this

mysql          5.7                   314749b3a5c   17 hours ago    431MB

Create Mysql Container:

Let’s create the MySQL container. To create a MySQL container, use the following command.

docker run --name=cn-mysql -d -p 3316:3306 --env="MYSQL_ROOT_PASSWORD=root1249" mysql:5.7

Note: use your own MySQL root password instead of root1249 and the port instead of 3316 and container name instead of cn-mysql

This will create the container. We can see the container using the following command

docker container ls -a 
OR
docker ps -a

Enter into the Mysql server:

If we want to do the regular MySQL operation, then we need to enter the MySQL server inside docker as below

docker exec -it elint-mysql bash

Now login into MySQL using the command

mysql -u root -p

Use your own MySQL password which is used while creating a container i.e root1249

Now we can do operations like creating databases and users.

Creating Mysql User:

In order to create a MySQL user and give permission visit the tutorial, Create Mysql User and Grant Privileges

Let's create a user

create user 'username'@'%' identified by 'password';

Note: change your own username and password. If you need to connect your created user from any client, you should create the user with “%” which signifies, that you can connect this user from any host.

Now, let's grant privileges

grant all privileges on *.* to username;

Use the previously created username

flush privileges;
Share:

Install Docker on Ubuntu 20.04

In this tutorial, we will learn how to install docker on Ubuntu Linux.

Install docker using the repository:

For this, first set up the repository. Use the following command.

sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

Now, add docker's GPG key

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

Now give the sufficient permission

sudo chmod a+r /etc/apt/keyrings/docker.gpg

In order to set up the repository, use the following command

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Now for installing Docker use the following command, which will install the latest docker.

sudo apt-get update & sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Install Docker using .deb package:

If we might have a problem with installing the docker with the above or wants to install a specific version of the docker then using .deb package is a good solution.

Download the desired version of .deb from here

In order to test the ubuntu version use the following command

lsb_release -a

we can get the output as below

No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.3 LTS
Release:	20.04
Codename:	focal

Here, the codename is focal so We chose the same as above. Then browse to pool/stable/, choose amd64, armhf, arm64, or s390x, and download the .deb file

In order to test the CPU available use the following command

lscpu

Go to the download folder and execute the deb package using the following command

sudo dpkg -i docker-ce-cli_18.09.0_3-0_ubuntu-bionic_amd64.deb

Note: make sure to use your own version of the .deb package. Now start the docker

Now, we successfully install docker.

Check the Docker Version:

docker --version

Uninstall Docker:

Uninstall docker, CLI, Containerd, and Docker Compose packages using the following command

sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-compose-plugin

Now, delete all images, containers, and volumes

sudo rm -rf /var/lib/docker
 sudo rm -rf /var/lib/containerd

Share:

Tuesday, July 26, 2022

Setup Http client for API using OkHttp in Java

In this tutorial, we will learn how to use OkHttp for HTTP requests while consuming APIs.

OkHttp is an HTTP client which will do HTTP efficiently by loading faster and saving bandwidth. Using OkHttp is easy. Its request/response API is designed with fluent builders and immutability. It supports both synchronous blocking calls and async calls with callbacks.

Setup the OkHttp dependency:

If we are using the external Jar file, download the jar from okhttp maven.

Follow this tutorial for setting up the Jar file How to add external jar or library on IntelliJ IDEA project

Setup in maven project:

Add in pom.xml

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.10.0</version>
</dependency>

Setup in Gradle project:

Add in build.gradle under "dependencies"

dependencies {
//other dependencies
 
compile("com.squareup.okhttp3:okhttp:4.10.0")
}

Implementation:

Let's create a sample java class HttpClient.java and set up the OkHttp3 client.

import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response

class HttpClient {

    public static final MediaType JSON = MediaType.get("application/json; charset=utf-8")


    public static Response doGetRequest(url, String apiKey = '') {
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
        Request request = setHeadersConfig(requestBuilder, apiKey).build();
        Response response = getClient().newCall(request).execute()
        return response.body().string();
    }

    public static String doPostRequest(String json, String url, String apiKey = '') {
        RequestBody body = RequestBody.create(json, JSON)
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .post(body)
        Request request = setHeadersConfig(requestBuilder, apiKey).build();
        Response response = getClient().newCall(request).execute()
        return response.body().string()
    }

    public static String doDeleteRequest(String json, String url, String apiKey = '') {
        RequestBody body = RequestBody.create(json, JSON)
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .delete(body)
        Request request = setHeadersConfig(requestBuilder, apiKey).build();
        Response response = getClient().newCall(request).execute()
        return response.body().string()
    }

    private static Request.Builder setHeadersConfig(Request.Builder requestBuilder, String apiKey) {
        requestBuilder.header("Content-Type", "application/json")
                .header("X-MBX-APIKEY", apiKey)
        return requestBuilder
    }

    private static OkHttpClient getClient() {
        return new OkHttpClient()
    }
}

This class contains the setup for the post, get and delete request.

Method setHeadersConfig is for setting up the headers we used sample X-MBX-APIKEY header configuration to set the API key. You can use your desired header configuration there.

We can pass the post body by formatting the data in JSON string.

Please don't forget to handle the Exception.

Getting Status Code:

We can get the status code from the Response response object in the above example as below:

 Response response = getClient().newCall(request).execute()
        int statusCode = response.code()

Using it from Java classes:

All the methods are static so we can simply use it from other java classes as below:

HttpClient.doPostRequest(json, url, apiKey)
Share: