JAXP (JSR-206) in a nutshell

JAXP(JSR-206) covers following specifications:

  • DOM (org.w3c.dom package)
  • SAX (org.xml.sax package)
  • StAX/JSR-173 (java.xml.stream)
  • XSLT (javax.xml.transform)
  • XPath (javax.xml.xpath)
  • Validation (javax.xml.validation)
  • Datatypes (javax.xml.datatype)

Implemetations:

Xerces - Is an open source Java XML parser that provides DOM and SAX implementations that are compliant with the JAXP standard.
JDOM and DOM4J - Are open source Java XML parsers.

REST service path definition

Usually, RESTful service path is represented in format of /path, e.g {context}/{root}/{version}/{resource} in this, the context is the most volatile portion. The root is web.xml, annotation driven. 

The rules are:
1. If defined in web.xml, then url pattern is pre/appended to @Path annotations
2. If a class is defined within an @Application, then it will inherit the base of the annotation

3. All methods are composite paths of @Path parameters from both the class annotation and any method annotations + supporting verbs.

SCM release version convension, major minor patch build

<major>.<minor>.<patch>.<build>
e.g 1.0.1

  • Major versions must increment when significant changes or breaking changes are made
    • Examples: 
      • Remove a method
      • Change a signature
      • Change a return type
      • Remove an API
  • Minor versions must increment when minor additions are made that and backward compatibility is maintained
    • Examples: 
      • add a new method
      • add a new variable
      • add enhancement
  • Patch versions are incremented when functional (inner method) changes are made to fix behavior problems
    • Example: 
      • Change the business logic or a method to perform calculations differently
  • Build versions are incremented when new build is created

CATALINA_OPTS v.s JAVA_OPTS

CATALINA_OPTS and JAVA_OPTS are two major environment variables used in tomcat and other applications. Both are used in the catalina.sh startup and shutdown scripts for Tomcat. They are described in comments within that file as:
[JAVA_OPTS] (optional) Java runtime options used when the "start", "stop" or "run" command is executed 
[CATALINA_OPTS] (optional) Java runtime options used when the "start" or "run" command is executed

Then why are there two different variables? What's the key difference?
Firstly, anything specified in EITHER variable is passed, identically, to the command that starts up Tomcat - the "start" or "run" command - but only values set in JAVA_OPTS are passed to the "stop" command. That probably doesn't make any difference to how Tomcat runs in practise as it only effects the end of a run, not the start.
Secondly, other applications may also use JAVA_OPTS, but only Tomcat will use CATALINA_OPTS. So if setting environment variables for use only by Tomcat, it's best to use CATALINA_OPTS, whereas if setting environment variables to be used by other java applications as well, such as by JBoss, it's better to put settings in JAVA_OPTS.

[Leetcode] N Queens in Java

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Thoughts: with recursive check(DFS) to find the solution and add each solution to result as ArrayList<String>

 public class Solution {  
   public List<List<String>> solveNQueens(int n) {  
     List<List<String>> result = new ArrayList<List<String>>();  
     int[] location = new int[n];  
     dfs(result, location, 0, n);  
     return result;  
   }  
   public void dfs(List<List<String>> result, int[] loc, int curRow, int n){  
     if (curRow == n){  
       addResult(result, loc, n);  
     } else {  
       for (int i=0; i<n; i++){  
         loc[curRow] = i;  
         if (isValid(loc, curRow)){  
           dfs(result, loc, curRow+1, n);  
         }  
       }  
     }  
   }  
   public boolean isValid(int[] loc, int curRow){  
     for (int i=0; i<curRow; i++){  
       if (loc[curRow] == loc[i] || Math.abs(loc[curRow] - loc[i]) == (curRow - i)){  
         return false;  
       }  
     }  
     return true;    
   }  
   public void addResult(List<List<String>> result, int[] loc, int n){  
     List<String> sol= new ArrayList<String>();  
     for (int i=0; i<n; i++){  
       StringBuilder sb = new StringBuilder();  
       for (int j=0; j<n; j++){  
         if (loc[i] == j){  
           sb.append("Q");  
         } else {  
           sb.append(".");  
         }  
       }  
       sol.add(sb.toString());  
     }  
     result.add(sol);  
   }  
 }  

Java Best Practices and Tips


  •  10-50-500 Rule

In big software packages, maintaining code becomes very challenging. Developers who join fresh ongoing support projects, often complain about: Monolithic Code, Spaghetti Code. There is a very simple rule to avoid that or keep the code clean and maintainable: 10-50-500.
10: No package can have more than 10 classes.
50: No method can have more than 50 lines of code.
500: No class can have more than 500 lines of code.

  • SOLID Class Design Principles

Single responsibility principle - A class should have one and only one task/responsibility. If class is performing more than one task, it leads to confusion.
    Open/closed principle - The developers should focus more on extending the software entities rather than modifying them.
      Liskov substitution principle - It should be possible to substitute the derived class with base class.
        Interface segregation principle - It’s like Single Responsibility Principle but applicable to interfaces. Each interface should be responsible for a specific task. The developers should need to implement methods which he/she doesn’t need.
          Dependency inversion principle - Depend upon Abstractions- but not on concretions. This means that each module should be separated from other using an abstract layer which binds them together.
          • Design Patterns
          Design patterns help developers to incorporate best Software Design Principles in their software. They also provide common platform for developers across the globe. They provide standard terminology which makes developers to collaborate and easier to communicate to each other.
          • Use Collections Correctly
          Java have set of build-in collection data structures available for usage out of box. List, Map, Set, Array. The developers are encouraged to use collections as extensively as possible for the following reasons:
          - Use of collections makes the code reusable and interoperable.
          - Collections make the code more structured, easier to understand and maintainable.
          - Out of the box collection classes are well tested so the quality of code is good.

          Since Vector and Hashtable are heavily synchronized even for read operations, they can present some challenging problems in performance tuning.
          • Avoid Floating Point Numbers
          Floating point numbers should be used only if they are absolutely necessary. For example, representing Rupees and Paise using Floating Point numbers can be Problematic – BigDecimal should instead be preferred. Floating point numbers are more useful in measurements.
          • Avoid deadlock by using correct lock sequence
          References 
          - https://docs.oracle.com/cd/A97688_16/generic.903/bp/java.htm 
          - https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

          Eclipse Error: Dynamic Web Module 3.0 requires Java 1.6 or newer.

          Problem: when creating maven project in eclipse, it always complains:
                                    - Dynamic Web Module 3.0 requires Java 1.6 or newer.
                       

          Solution:
          1. In eclipse, find facets template file by name : org.eclipse.wst.common.project.facet.core.xml
          2. Edit the file and change the dynamic web module version in this line to 3.0 - <installed facet="jst.web" version="2.5"/>
          3.  <?xml version="1.0" encoding="UTF-8"?>  
             <faceted-project>  
              <fixed facet="wst.jsdt.web"/>  
              <installed facet="jst.web" version="3.0"/>  
              <installed facet="wst.jsdt.web" version="1.0"/>  
              <installed facet="java" version="1.8"/>  
             </faceted-project>  
            
          4. update web.xml to 3.0 dynamic web module as well. e.g
          5.  <web-app xmlns="http://java.sun.com/xml/ns/javaee"   
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
               xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
                         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
                         version="3.0">  
               <display-name>Servlet 3.0 Web Application</display-name>  
             </web-app>  
            
          6. in IDE(e.g eclipse), right click <project name> -> maven -> update projects.
          7. Done!

          NOTE: if there is still error
          Q: Dynamic Web Module 3.0 requires Java 1.6 or newer
          A: add following in pom or compilation setting

                <build>  
                     <directory>${basedir}/target</directory>  
                     <plugins>  
                          <plugin>  
                               <groupId>org.apache.maven.plugins</groupId>  
                               <artifactId>maven-compiler-plugin</artifactId>  
                               <version>3.3</version>  
                               <configuration>  
                                    <source>1.8</source>  
                                    <target>1.8</target>  
                                    <showWarnings>true</showWarnings>  
                               </configuration>  
                          </plugin>  
                     </plugins>  
                </build>