Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Friday, June 11, 2021

Solr 6 Java version upgrade from Jdk1.8.0_161 to Jdk-11.0.11 on centos platform

 

Follow the steps given below to upgrade the SOLR 6.x Java version:

  • Stop Solr instance if running already

$ sudo systemctl stop solr

 

# If system service is not configured then use following command:

 

$ sudo /opt/solr/bin/solr stop -all

  • Take backups in case something happens after upgrade, so you have a copy of previous setup
    • Take backup of /opt/solr/bin directory into a backup directory. E.g. ‘/home/alfweb/solrbackups’

# Create a backup directory if not already available.

 

$ sudo mkdir /home/alfweb/solrbackups

 

# Create a zip package of ‘/opt/solr/bin’ directory and move to solr backup directory

 

$ sudo zip -r /home/alfweb/solrbackups/solr-bin-dir-backup.zip /opt/solr/bin

 

    • Take backup of /opt/solr/server/solr directory which contains configs and indexes for cores created under ‘solr’ directory. If this directory contains indexes then they will also be backed up.

# Create a zip package of ‘/opt/solr/server/solr’ directory and move to solr backup directory

 

$ sudo zip -r /home/alfweb/solrbackups/solr-server-solr-dir-backup.zip /opt/solr/server/solr

 

    • Take backup of index data directory, If data directory is mounted at some different location other than ‘/opt/solr/server/solr’ directory which is usually default directory for configs and indexes.

# For example if solr index data directory is in ‘/var/solr/data’ directory then :

 

$ sudo zip -r /home/alfweb/solrbackups/var-solr-data-dir-backup.zip /var/solr/data

 

  • Install Java 11 (this is open jdk version of java 11 installation) using repository if server can connect to internet
    • Update packages, it is a best practice to start with an updated operating system before installing a package. If you have not done so, use the following command to update OS and reboot:


$ sudo yum update -y

$ sudo reboot 


    • Update packages, it is a best practice to start with an updated operating system before installing a package. If you have not done so, use the following command to update OS and reboot:


$ sudo yum install java-11-openjdk-devel


    • This will install java11 in following directory: /usr/lib/jvm/java-11
    • Run following command to check what is the default java version 

 

$ sudo yum java -version

 

If you see java version other than java-11, then you can switch and set the default version as java-11. Run the following command: 


 $ sudo alternatives --config java


This will prompt you to select the version you want to set as default. Select a number from the list, e.g. if java-11 is at number 2, then type '2' and press enter. Revalidate the java version again.

  • Go to Solr installation directory i.e. “/opt/solr” and take a backup of “solr.in.sh” file. 

$ sudo cp /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.bak

# If you used “install_solr_service.sh” script to install solr, then it will create a default ‘solr.in.sh’ file under ‘/etc/default/’ directory. In order to update the JVM parameter, you have to edit ‘/etc/default/solr.in.sh’ file. Take the backup of default solr.in.sh file:

$ sudo cp /etc/default/solr.in.sh /etc/default/solr.in.sh.bak


  • Open the “solr.in.sh” file in edit mode and update the following:

$ sudo vim /opt/solr/bin/solr.in.sh

# If you used “install_solr_service.sh” script to install solr, then it will create a default ‘solr.in.sh’ file under ‘/etc/default/’ directory. In order to update the JVM parameter, you have to edit ‘/etc/default/solr.in.sh’ file.

$ sudo vim /etc/default/solr.in.sh


 

#Comment out SOLR_HEAP variable

#SOLR_HEAP="512m"

 

#Uncomment SOLR_JAVA_MEM variable and set the value accordingly based on data/indexes and available memory. Note that, set the memory as per your need.

SOLR_JAVA_MEM="-Xms4g -Xmx4g"

 

#Comment out existing GC_LOG_OPTS and GC_TUNE variables and add new variable with same name and new values

################################ SOLR 6.1 Java 11 Upgrade GC_LOG_OPTS settings [Start] ################

#Comment out existing settings and set the variable with updated parameters per java11. 

GC_LOG_OPTS="-Xlog:gc*,safepoint,age*,ergo*:file=/var/solr/logs/solr_gc-%p-%t.log:tags,uptime,time,level:filecount=10,filesize=50m"

#Make sure logs directory is present and correct, some setups specially production setup doesn’t keep logs under ‘/opt/solr/server/logs directory’ (this is default directory for logs), instead logs are configured to be written under ‘/var/solr/logs’ directory. In this case update the path for GC_LOG_OPTS file parameter.

################################ SOLR 6.1 Java 11 Upgrade GC_LOG_OPTS settings [End] ##################

################################ SOLR 6.1 Java 11 Upgrade GC_TUNE settings [Start] ################

# Comment out existing setting and set the variable with updated parameters per java11. The below params are optimized for the system I worked with, you can set the params as per your need if planning to use G1GC

GC_TUNE="-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+UseLargePages -XX:G1HeapRegionSize=2m -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=70 -XX:+UseStringDeduplication -XX:+DisableExplicitGC"

 

Instructions for G1HeapRegionSize:


Heap Size

G1HeapRegionSize

< 4GB

1MB

4-8GB

2MB

8-16GB

4MB

16-32GB

8MB

32-64GB

16MB

>64GB

32MB


################################ SOLR 6.1 Java 11 Upgrade GC_TUNE settings [End] ##################

 

  • Save the file and Restart the solr

$ sudo systemctl restart solr 

# If system service is not configured then use following command:

$ sudo -u solr /opt/solr/bin/solr restart -all

  • Validate the java version in SOLR Admin.


Setup solr as a service (If not already setup):

  • Create a service named solr.service under /etc/systemd/system directory
  • Follow the below given instructions to create and start the service.

$ sudo vim /etc/systemd/system/solr.service

# Add the below instructions to solr.service unit

[Unit]

Description=Sitecore8 search service

After=syslog.target network.target

[Service]

Type=forking

ExecStart=/opt/solr/bin/solr start -all

PIDFile=/opt/solr/bin/solr-8983.pid

ExecStop=/opt/solr/bin/solr stop -all

SuccessExitStatus=0

Restart=always

User=solr

Group=Solr

[Install]

WantedBy=multi-user.target

# Reload daemon

$ sudo systemctl daemon-reload

# Start and enable solr to automatically start at boot time

$ sudo systemctl start solr

$ sudo systemctl enable solr

# Check status

$ sudo systemctl status solr




Useful resources:




Thursday, February 9, 2017

Switch statement implementation for class type using enum


Switch statement in most languages including Java, C++, C# etc. is a kind of jump table. It is considered when you have a long if-else ladder. It is considered faster than if-else ladder because conditions can be looked up directly. Whereas in if-else ladder each condition will be evaluated until a true condition is met.

JVM loads the cases (condition values) and compares with the input value and allows to jump to the case without evaluating each case (condition). That's the reason it is faster than if-else ladder.
Each case (condition) has a "break" statement which allows the execution to exit once condition is fulfilled.

It is recommended to use switch statement if the "if-else" ladder is long (has more than 3 conditions).

As per Oracle documentation:

"Unlike if-then and if-then-else statements, the switch statement can have a number of possible execution paths. A switch works with the byteshortchar, and int primitive data types. It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: CharacterByteShort, and Integer (discussed in Numbers and Strings)."

Java doesn't support switch statement for Classes other than mentioned above. But there may be cases when you want to use switch statement. We will see the usage here by taking a problem statement.

Let's say i have a Shape interface and there are multiple implementations of the Shape. And i have a requirement to call a method from one of the implementation class which matches the given instance using "instanceof" operator.

e.g.

 
if(shape instanceof Square) {

    shape.printShape();

} else if (shape instanceof Rectangle) {

    shape.printShape();

} else if (shape instanceof Triangle) {

    shape.printShape();

} else if (shape instanceof Circle) {

    shape.printShape();

} else if (shape instanceof Cube) {

    shape.printShape();

} .....
...... and so on.



Now if i want to use switch statement here then it's not supported directly. But there some design patterns which can be followed to achieve the goal. Here we will use java enum type to solve our problem.

Let's take same example as given above and try to solve the problem using enum.
We will do following steps:

1- We will create an enum type where we will declare enum constants as class types.
2- We will declare a map which will be populated with class names of above declared enums.
3- We will declare a method which will return the class type constant based on given name (string)


//ShapesEnum.java
package com.switchtest;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public enum ShapesEnum {

       SQUARE(Square.class), RECTANGLE(Rectangle.class), CIRCLE(Circle.class);

       private final String className;

       ShapesEnum(final Class<?> cls) {
             this.className = cls.getName();
       }

       //Initialize a map which will store the class names of all shape types
       private static final Map<String, ShapesEnum> SHAPES =
                             new ConcurrentHashMap<String, ShapesEnum>();

       //Populate the map with values
       static {
             for (final ShapesEnum shape : values()) {
                    SHAPES.put(shape.className, shape);
             }
       }

       public static ShapesEnum getShape(final String className) {
             return SHAPES.get(className);
       }
}



//Shape.java
package com.switchtest;

public interface Shape {
       void displayName();
}




//Square.java
package com.switchtest;


public class Square implements Shape {
      
       @Override
       public void displayName() {
             System.out.println("I am Square..");
       }

}

  
//Rectangle.java
package com.switchtest;


public class Rectangle implements Shape {
      
       @Override
       public void displayName() {
             System.out.println("I am Rectangle..");
       }

}

//Circle.java
package com.switchtest;

public class Circle implements Shape{

       @Override
       public void displayName() {
             System.out.println("I am Circle..");          
       }
}


//SwitchTest.java
package com.switchtest;

public class SwitchTest {
       public static void main(String[] argv) throws Exception {
             final Shape square = new Square();
             printShape(square);
            
             final Shape rectangle = new Rectangle();
             printShape(rectangle);
            
             final Shape circle = new Circle();
             printShape(circle);
       }

       private static void printShape(final Shape shape) {
             switch (ShapesEnum.getShape(shape.getClass().getName())) {
             case SQUARE:
                    shape.displayName();
                    break;
             case RECTANGLE:
                    shape.displayName();
                    break;
             case CIRCLE:
                    shape.displayName();
                    break;
             default:
                    System.out.println("No shape selected.");
                    break;
             }
       }
}



Output:

I am Square..
I am Rectangle..
I am Circle..