FANDOM


Java

JVM startup command-line

  1. :: Starts stand-alone MyApp server
  2. ::
  3. :: @author Sangmoon Oh
  4. :: @since 2015-01-01
  5.  
  6. @ echo off
  7. setLocal enableDelayedExpansion
  8.  
  9. if not exist "%JAVA_HOME%\bin\java.exe" (
  10.   echo.
  11.   echo Fail to run
  12.   echo JDK 1.6 ^(32-bit^) or higher and 'JAVA_HOME' environment variable for it are required.
  13.   goto :END
  14. )
  15. echo JAVA_HOME = %JAVA_HOME%
  16.  
  17. if exist "%JAVA_HOME%\release" (
  18.   for /F "tokens=2 delims==" %%x in ('findstr "JAVA_VERSION" "%JAVA_HOME%\release"') do set JAVA_VERSION=%%~x
  19.   for /F "tokens=2 delims==" %%x in ('findstr "OS_ARCH" "%JAVA_HOME%\release"') do set OS_ARCH=%%~x
  20.  
  21.   echo JAVA_VERSION = !JAVA_VERSION!
  22.   echo OS_ARCH = !OS_ARCH!
  23.  
  24.   if !OS_ARCH! equ amd64 (
  25.     echo.
  26.     echo The provided JDK is 64-bit. This application requires 32-bit JDK.
  27.     goto :END
  28.   )
  29. )
  30.  
  31. if not exist "%MYAPP_HOME%" (
  32.   echo.
  33.   echo 'MYAPP_HOME' environment variable is not set or has inappropriate value.
  34.   goto :END
  35. )
  36. if not exist "%OPENCV_DIR%" (
  37.   echo.
  38.   echo 'OPENCV_DIR' environment variable is not set or has inappropriate value.
  39.   goto :END
  40. )
  41. echo MYAPP_HOME = %MYAPP_HOME%
  42. echo OPENCV_DIR = %OPENCV_DIR%
  43.  
  44. set CLASSPATH=%MYAPP_HOME%\conf;%MYAPP_HOME%\lib\*
  45.  
  46. :: For more on JVM options, refer http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
  47. set JVM_ARGS=-server -Xms256m -Xmx256m -XX:MaxPermSize=256M
  48. set JVM_ARGS=%JVM_ARGS% -XX:NewRatio=2 -XX:SurvivorRatio=8
  49. if %JAVA_VERSION:~0,3% equ 1.7 (
  50.   set JVM_ARGS=%JVM_ARGS% -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1ReservePercent=10
  51. ) else (
  52.   set JVM_ARGS=%JVM_ARGS%  -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseNUMA
  53. )
  54. set JVM_ARGS=%JVM_ARGS% -verbose:gc -Xloggc:"%MYAPP_HOME%\log\jvm\gc_%%t.log" -XX:+PrintGCDateStamps -XX:+PrintGCDetails
  55. set JVM_ARGS=%JVM_ARGS% -XX:NativeMemoryTracking=detail
  56. set JVM_ARGS=%JVM_ARGS% -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics
  57. set JVM_ARGS=%JVM_ARGS% -XX:+DisableExplicitGC
  58. set JVM_ARGS=%JVM_ARGS% -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="%MYAPP_HOME%\jvm"
  59. set JVM_ARGS=%JVM_ARGS% -XX:ErrorFile="%MYAPP_HOME%\jvm\hs_err_pid%%p.log"
  60. set JVM_ARGS=%JVM_ARGS% -Djava.library.path="%OPENCV_DIR%\..\..\java\x86"
  61. set JVM_ARGS=%JVM_ARGS% -Dfile.encoding=UTF-8
  62. set JVM_ARGS=%JVM_ARGS% -Duser.timezone=Asia/Seoul
  63. rem set JVM_ARGS=%JVM_ARGS% -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
  64. set JVM_ARGS=%JVM_ARGS% -Dcom.sun.management.jmxremote.port=3333
  65. set JVM_ARGS=%JVM_ARGS% -Dcom.sun.management.jmxremote.ssl=false
  66. set JVM_ARGS=%JVM_ARGS% -Dcom.sun.management.jmxremote.authenticate=false
  67. set JVM_ARGS=%JVM_ARGS% -Dlog.level.root=TRACE
  68. set JVM_ARGS=%JVM_ARGS% -Dlog.level.spring=DEBUG
  69. set JVM_ARGS=%JVM_ARGS% -Dlog.level.mybatis=DEBUG
  70. set JVM_ARGS=%JVM_ARGS% -Dlog.timezone=Asia/Seoul
  71.  
  72. echo ************************************************
  73. echo '"%JAVA_HOME%\bin\java" %JVM_ARGS% -cp "%CLASSPATH%" myapp.StandaloneServer'
  74. echo ************************************************
  75.  
  76. "%JAVA_HOME%\bin\java" %JVM_ARGS% -cp "%CLASSPATH%" myapp.StandaloneServer
  77.  
  78. :END
  79. endLocal

Waiting Enter key press on the console

Using java.io.InputStream.read(), java.util.Scanner.hasNextLine(), or java.util.Scanner.nexLine() may make the code simple, but they are much bad on behalf of performance in concurrent environment or debugging situation. To make other thread or debugging session unaffected as possible, it is better to use java.io.InputStream.available() with loop.

  1.    ...
  2.    System.out.println("Press [Enter] key to start.");
  3.    int cnt;
  4.    while((cnt = System.in.available()) < 1){
  5.       Thread.sleep(500);
  6.    }
  7.    while(cnt-- > 0) System.in.read();
  8.    ...
  9.  
  10.    System.out.println("Press [Enter] key to proceed.");
  11.    while((cnt = System.in.available()) < 1){
  12.       Thread.sleep(500);
  13.    }
  14.    while(cnt-- > 0) System.in.read();
  15.    ...
  16.  
  17.    System.out.println("Press [Enter] key to end.");
  18.    while((cnt = System.in.available()) < 1){
  19.       Thread.sleep(500);
  20.    }
  21.    while(cnt-- > 0) System.in.read();

You should call the available() in the loop, because it is non blocking. The keys pressed before Enter should be consumed before the next wait.

wait, notify and notifyAll

The thread should own the monitor of the instance to call wait, notify or notifyAll before the call. So, the call of these basic method should be always located inside synchronized block.

A thread can wake up by unexpected or unpredictable reason, so the call of wait and the logic to process after wake-up should be guarded by loop.

So, the typical code block for calling wait is

  1.    ...
  2.    final Object obj = new Object;
  3.    ...
  4.  
  5.    synchronized (obj) {
  6.          while (<condition does not hold>)
  7.              obj.wait(timeout);
  8.          ... // Perform action appropriate to condition
  9.    }
  10.  
  11.    ...

And for notifyAll

  1.    ...
  2.    final Object obj = new Object;
  3.    ...
  4.  
  5.    synchronized (obj) {
  6.       //Perform some action to release the hold condition
  7.       obj.notifyAll();
  8.       ...
  9.    }
  10.  
  11.    ...


Using Lock class of java.util.concurrent.locks package

  1.  class X {
  2.    private final ReentrantLock lock = new ReentrantLock();
  3.    // ...
  4.  
  5.    public void m() {
  6.      lock.lock();  // block until condition holds
  7.      try {
  8.        // ... method body
  9.      } finally {
  10.        lock.unlock()
  11.      }
  12.    }
  13.  }


Controlling start-up and detecting end of thread executions using CountDownLatch

  1. class Control{
  2.  
  3.    private int numOfTasks;
  4.    private CountDownLatch startCntDwn = new CountDownLatch(1);
  5.    private CountDownLatch endCntDwn = new CountDownLatch(numOfTasks);
  6.  
  7.    //...
  8.  
  9.    public void execute() throws Exception{
  10.       ExecutorService executor = Executors.newFixedThreadPool(numOfTasks);
  11.  
  12.       //conditions for the tasks
  13.       List<Condition> conditions = new ArrayList<Condition>(numOfTasks);
  14.       //tasks
  15.       List<Task> tasks = new ArrayList<Task>(numOfTasks);
  16.       //futures to get results
  17.       List<Future<Result>> futures = new ArrayList<Future<Result>>(numOfTasks);
  18.       //results of tasks
  19.       List<Result> results = new ArrayList<Result>(numOfTasks);
  20.  
  21.       Condition cndt = null;
  22.       for(int i = 0; i < numOfTasks; i++){
  23.          cndt = new Condition();
  24.          //setup Condition object for each task
  25.          tasks.add(new Task(cndt, startCntDwn, endCntDwn));
  26.       }
  27.  
  28.       for(Task task: tasks){
  29.          futures.add(executor.submit(task));
  30.       }
  31.  
  32.       startCntDwn.countDown();
  33.       endCntDwn.await();
  34.  
  35.       for(Future<Result> future : futures){
  36.          results.add(future.get());
  37.       }
  38.  
  39.       //manipulating results
  40.  
  41.       executor.shutdown();
  42.    }
  43.  
  44.    public long getNumberOfTasks(){ return this.numOfTasks; }
  45.  
  46.    public long getNumberOfRunningTasks(){
  47.       if(this.startCntDwn.getCount() == 1) return 0;
  48.       else return this.endCntDwn.getCount();
  49.    }
  50. }
  51.  
  52. class Task implements Callable<Result>{
  53.  
  54.    private CountDownLatch startCntDwn;
  55.    private CountDownLatch endCntDwn;
  56.  
  57.    //other fields to do task.
  58.  
  59.    public Task(Condition condition, CountDownLatch start, CountDownLatch end){
  60.       this.startCntDwn = start;
  61.       this.endCntDwn = end;
  62.    }
  63.  
  64.    public Result call() throws Exception{
  65.       Result result = null;
  66.       this.startCntDwn.await();
  67.  
  68.       //do its own task and create result;
  69.  
  70.       this.endCntDwn.countDown();
  71.       return result;
  72.    }
  73. }
  74.  
  75. class Condition{
  76.  
  77. }
  78.  
  79. class Result{
  80.  
  81. }


Lazy initialization of field

Lazy initialization of instance field using double-checked locking

Prior to JDK 1.5, double-checked locking is not safe with Java because the reordering of object publication and initialization can not be controlled. But as of JDK 1.5, volatile is specified not to be reordered, so it become possible to use safely double-checked locking with volatile field.

A typical code would be like this :

  1. @ThreadSafe
  2. public class Worker{
  3.  
  4.    private volatile Resource resource = null; //creating resource is expensive
  5.    private final String lock = String.valueOf(-1);  //avoid String intern.
  6.  
  7.    @GuardedBy("lock")
  8.    public Resource getResource(){
  9.       Resource r = resource;
  10.       if(r == null){ //first check
  11.          synchronized(lock){
  12.             r = resource;
  13.             if(r == null){ //second check
  14.                resource = r = new Resource();
  15.             }
  16.          }
  17.       }
  18.       return r;
  19.    }
  20.    
  21.    ...
  22. }

In above sample code, note that the lock object is define to be final, because reference on non final field can change any time. The above code can be enhanced using java.util.concurrent.locks.Lock

  1. @ThreadSafe
  2. public class Worker{
  3.  
  4.    private volatile Resource resource = null; //creating resource is expensive
  5.    private final Lock lock = new ReentrantLock();
  6.  
  7.    @GuardedBy("lock")
  8.    public Resource getResource(){
  9.       Resource r = resource;
  10.       if(r == null){ //first check
  11.          lock.lock()
  12.          try{
  13.             r = resource;
  14.             if(r == null){ //second check
  15.                resource = r = new Resource();
  16.             }
  17.          }catch(Exception ex){
  18.             //write log and re-throw the exception
  19.          }finally{
  20.             lock.unlock();
  21.          }
  22.       }
  23.       return r;
  24.    }
  25.    
  26.    ...
  27. }

The following is a simple Spring container locator class.

  1. /**
  2.  * Locates Spring containers.
  3.  * <p>
  4.  * This class can be used to access Spring container from where DI is not possible.
  5.  * <p>
  6.  * Note that this class is thread-safe and caches the Spring containers
  7.  *
  8.  * @version 1.0, 2015-08-13, Sangmoon Oh, Initial version
  9.  * @author Sangmoon Oh
  10.  * @since 2015-08-13
  11.  */
  12. @Singleton
  13. @ThreadSafe
  14. public class SpringContainerLocator {
  15.  
  16.   private final Logger logger = LoggerFactory.getLogger(this.getClass());
  17.  
  18.   private static SpringContainerLocator instance;
  19.  
  20.   private volatile Map<String, ConfigurableApplicationContext> cache = new HashMap<String, ConfigurableApplicationContext>();
  21.  
  22.   private final Lock cacheLock = new ReentrantLock();
  23.  
  24.   /**
  25.    * Test purpose filed to confirm concurrency in hight congestion.
  26.    */
  27.   private final AtomicInteger count = new AtomicInteger(0);
  28.  
  29.   /**
  30.    * Gets the count of Spring container loadings.
  31.    * This method is test only purpose.
  32.    */
  33.   protected int getCount(){ return this.count.intValue(); }
  34.  
  35.   static{
  36.     //No need on lazy initialization.
  37.     if(instance == null){ instance = new SpringContainerLocator(); }
  38.   }
  39.  
  40.   private SpringContainerLocator(){}
  41.  
  42.   public static SpringContainerLocator getSingleton(){ return instance; }
  43.  
  44.   /**
  45.    * Gets the Spring container configured by the specified configuration file.
  46.    * <p>
  47.    * Currently, the location of Spring configuration file should be
  48.    * <emp>classpath relative</emp>.
  49.    * <p>
  50.    * The loaded Spring container will be registered shutdown hook, so you don't need to do in your code.
  51.    *
  52.    * @param configLoc The location of configuration file on classpath. such as 'foo/bar/spring.xml'
  53.    * @return The Spring container configured by the specified configLoc.
  54.    */
  55.   @GuardedBy("cacheLock")
  56.   public ApplicationContext getSpringContainer(@NotBlank String configLoc){
  57.     Validate.isTrue(StringUtils.isNotBlank(configLoc), "The location of configuration should be specified.");
  58.     ConfigurableApplicationContext container = cache.get(configLoc);
  59.  
  60.     if(container == null){ //first check
  61.       cacheLock.lock();
  62.       try{
  63.         container = cache.get(configLoc);
  64.         if(container == null){ //send check
  65.           container = new ClassPathXmlApplicationContext(configLoc);
  66.           container.registerShutdownHook();
  67.           cache.put(configLoc, container);
  68.           int cnt = this.count.incrementAndGet();
  69.           logger.info("The {}-th loading of Spring container: {}", cnt, configLoc);
  70.         }
  71.       }catch(Exception ex){
  72.         logger.error("Fail to load spring container whose configuration is" + configLoc + " on classpath.", ex);
  73.         throw new RuntimeException("Fail to load spring container whose configuration is" + configLoc + " on classpath.", ex);
  74.       }finally{
  75.         cacheLock.unlock();
  76.       }
  77.     }
  78.  
  79.     return container;
  80.   }
  81. }

Lazy initialization of static field using initialization on demand holder class

On behalf of the characteristics of class loading and static initialization, static field can be safely lazy initialized using holder class without locking.

JVM load classes in lazy way and JVM run static initilizers at class initilization time which is after class loading but before the class is used by any thread. So, the static holder class having static field like the below would be lazy initialized in safe way.

  1. public class Worker{
  2.  
  3.    private static class ResourceHolder{
  4.       public static Resource resource = new Resource();
  5.    }
  6.  
  7.    public static Resource getResource(){
  8.       return ResourceHolder.resource;
  9.    }
  10.    
  11.    ...
  12. }

More readings

More code samples

CommonAnnotationBeanPostProcessor.findResourceMetadata method of Spring framework

The following code from Spring framework uses double-checked locking for non-volatile field.

Is it safe ?

Assuming ConcurrentHashMap.put method may not be so complicated to expose stale values to threads and the local codes inside second check block (inner if clause checking metadata == null) would not be reordered with ConcurrentHashMap.put method execution, the below code could be almost safe ?

  1. package org.springframework.context.annotation;
  2.  
  3. public class CommonAnnotationBeanPostProcessor extends ...{
  4.  
  5.   ...
  6.   private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
  7.   new ConcurrentHashMap<Class<?>, InjectionMetadata>();
  8.  
  9.   ...
  10.  
  11.   private InjectionMetadata findResourceMetadata(final Class clazz) {
  12.     // Quick check on the concurrent map first, with minimal locking.
  13.     InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
  14.     if (metadata == null) {
  15.       synchronized (this.injectionMetadataCache) {
  16.         metadata = this.injectionMetadataCache.get(clazz);
  17.         if (metadata == null) {
  18.           final InjectionMetadata newMetadata = new InjectionMetadata(clazz);
  19.           ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
  20.             public void doWith(Field field) {
  21.               if (webServiceRefClass != null
  22.                   && field.isAnnotationPresent(webServiceRefClass)) {
  23.                 if (Modifier.isStatic(field.getModifiers())) {
  24.                   throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
  25.                 }
  26.                 newMetadata.addInjectedField(new WebServiceRefElement(field, null));
  27.               }
  28.               else if (ejbRefClass != null
  29.                   && field.isAnnotationPresent(ejbRefClass)) {
  30.                 if (Modifier.isStatic(field.getModifiers())) {
  31.                   throw new IllegalStateException("@EJB annotation is not supported on static fields");
  32.                 }
  33.                 newMetadata.addInjectedField(new EjbRefElement(field, null));
  34.               }
  35.               else if (field.isAnnotationPresent(Resource.class)) {
  36.                 if (Modifier.isStatic(field.getModifiers())) {
  37.                   throw new IllegalStateException("@Resource annotation is not supported on static fields");
  38.                 }
  39.                 if (!ignoredResourceTypes.contains(field.getType().getName())) {
  40.                   newMetadata.addInjectedField(new ResourceElement(field, null));
  41.                 }
  42.               }
  43.             }
  44.           });
  45.           ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
  46.             public void doWith(Method method) {
  47.               if (webServiceRefClass != null
  48.                   && method.isAnnotationPresent(webServiceRefClass)
  49.                   &&
  50.                   method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
  51.                 if (Modifier.isStatic(method.getModifiers())) {
  52.                   throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
  53.                 }
  54.                 if (method.getParameterTypes().length != 1) {
  55.                   throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
  56.                 }
  57.                 PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
  58.                 newMetadata.addInjectedMethod(new WebServiceRefElement(method, pd));
  59.               }
  60.               else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass) &&
  61.                   method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
  62.                 if (Modifier.isStatic(method.getModifiers())) {
  63.                   throw new IllegalStateException("@EJB annotation is not supported on static methods");
  64.                 }
  65.                 if (method.getParameterTypes().length != 1) {
  66.                   throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
  67.                 }
  68.                 PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
  69.                 newMetadata.addInjectedMethod(new EjbRefElement(method, pd));
  70.               }
  71.               else if (method.isAnnotationPresent(Resource.class) &&
  72.                   method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
  73.                 if (Modifier.isStatic(method.getModifiers())) {
  74.                   throw new IllegalStateException("@Resource annotation is not supported on static methods");
  75.                 }
  76.                 Class[] paramTypes = method.getParameterTypes();
  77.                 if (paramTypes.length != 1) {
  78.                   throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
  79.                 }
  80.                 if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
  81.                   PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
  82.                   newMetadata.addInjectedMethod(new ResourceElement(method, pd));
  83.                 }
  84.               }
  85.             }
  86.           });
  87.           metadata = newMetadata;
  88.           this.injectionMetadataCache.put(clazz, metadata);
  89.         }
  90.       }
  91.     }
  92.     return metadata;
  93.   }  
  94.  
  95.   ...
  96. }


Sample usage of ConcurrentHashMap

  • Can use ConcurrentHashMap in multi-threaded context without locking
  • Pay attention to putIfAbsent method.
  • Sample usage
    • org.apache.commons.lang3.time.FormatCache
    • In the following code, no locking is used to avoid concurrent update on cache. The update on the same key is avoided by putIfAbsent method. This type of approach that permit the concurrent trial of update is affordable 'cause format is somewhat light-weight object. For, more heavy-weight object, it is preferable to prevent the object to cache from being created more than once, by using locking
  1. abstract class FormatCache<F extends Format> {
  2.  
  3.     static final int NONE= -1;
  4.    
  5.     private final ConcurrentMap<MultipartKey, F> cInstanceCache
  6.         = new ConcurrentHashMap<MultipartKey, F>(7);
  7.    
  8.     private static final ConcurrentMap<MultipartKey, String> cDateTimeInstanceCache
  9.         = new ConcurrentHashMap<MultipartKey, String>(7);
  10.  
  11.     public F getInstance() {
  12.         return getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, TimeZone.getDefault(), Locale.getDefault());
  13.     }
  14.  
  15.     public F getInstance(final String pattern, TimeZone timeZone, Locale locale) {
  16.         if (pattern == null) {
  17.             throw new NullPointerException("pattern must not be null");
  18.         }
  19.         if (timeZone == null) {
  20.             timeZone = TimeZone.getDefault();
  21.         }
  22.         if (locale == null) {
  23.             locale = Locale.getDefault();
  24.         }
  25.         final MultipartKey key = new MultipartKey(pattern, timeZone, locale);
  26.         F format = cInstanceCache.get(key);
  27.         if (format == null) {          
  28.             format = createInstance(pattern, timeZone, locale);
  29.             final F previousValue= cInstanceCache.putIfAbsent(key, format);
  30.             if (previousValue != null) {
  31.                 // another thread snuck in and did the same work
  32.                 // we should return the instance that is in ConcurrentMap
  33.                 format= previousValue;              
  34.             }
  35.         }
  36.         return format;
  37.     }
  38.  
  39.     ...
  40. }

Generic method declaration

  • Case 1 : The type parameter is used only for method parameters, not for return type.

<T extends Object> is definitely different from <?>. The former means some fixed type, but the latter means unfixed type. In other words, with <?> the type can vary among executions.

  1. public static <T> PropertyMeta<?> getPropertyMeta(
  2.       @Nonnull String name, @Nonnull PropertyType type,
  3.       String title, String desc, Boolean required,
  4.       Double max, Boolean exclusiveMax, Double min,
  5.       Doolean exclusiveMin, Integer maxLen, Integer minLen,
  6.       T[] enums, String pattern, T defaultValue){
  7. ...
  8. }

Safe release of system resources

Classes in java.io or java.sql packages handle system resources on networking or file system. When using them, if the resources are not released in some circumstances, it may cause the performance degradation and finally more serious problems. Java has well-shaped code pattern or guideline to prevent these resource leakage.

  • Coding guideline
    • Process system resources entirely in A local scope
      • Do NOT define them as a member fields as possible.
      • Do NOT handle an object for a system resource in multiple methods passing them.
      • In usual coding pattern, java.sql.Connection is exceptional.
    • Process system resources in try/catch/finally statement.
    • Define variables for resource objects before try block.
    • Create, assign and use the resource objects IN try block
    • Close(release) the resource objects IN finally block, NEVER in try block.
      • Exceptionally when assigning multiple resource objects to a same variable in turn within loop, the resource objects of each iteration should be closed inside the loop (and so in try block). - See the 2nd sample below.
    • Close all the resource objects, when using multiple ones at the same time.
    • Close the resource objects in order from the underlying one, when the resource objects are in a stack together.
      • eg 1. new PrintStream(new BufferedOutputStream(new FileOutputStream(path, true, "utf-8")));
      • eg 2. Connection -> Statement -> ResultSet
    • AVOID to design the resource class as a parameter type and use the location of the resource as possible
    • The method that access the resource objects handed as a parameter, should NOT release or close the resource.
      • It's more intuitive and less confusing, the code block that create the resource object also release it.
  • Sample 1 - java.io package
  1.   public void writeEmployeesToFileMostUnsafe(@Nonnull List<Employee> emps, String path){
  2.  
  3.     FileOutputStream fos = null;
  4.     BufferedOutputStream bos = null;
  5.     PrintStream ps = null;
  6.  
  7.     try{
  8.       fos = new FileOutputStream(path);
  9.       bos = new BufferedOutputStream(fos, 1000);
  10.       ps =  new PrintStream(bos, true, "utf-8");
  11.  
  12.       for(Employee emp : emps){
  13.         ps.println(emp.toString());
  14.       }
  15.  
  16.       fos.close(); //may not be executed -> Unsafe
  17.       bos.close(); //may not be executed -> Unsafe
  18.       ps.close(); //may not be executed -> Unsafe
  19.     }catch(Exception ex){
  20.       this.logger.error("Can't write the Employee list", ex);
  21.       throw new RuntimeException("Can't write the Employee list", ex);
  22.     }
  23.   }
  24.  
  25.   public void writeEmployeesToFileUnsafe(@Nonnull List<Employee> emps, String path){
  26.  
  27.     FileOutputStream fos = null;
  28.     BufferedOutputStream bos = null;
  29.     PrintStream ps = null;
  30.  
  31.     try{
  32.       fos = new FileOutputStream(path);
  33.       bos = new BufferedOutputStream(fos, 1000);
  34.       ps =  new PrintStream(bos, true, "utf-8"); //may throw UnsupportedEncodingException
  35.  
  36.       for(Employee emp : emps){
  37.         ps.println(emp.toString());
  38.       }
  39.     }catch(Exception ex){
  40.       this.logger.error("Can't write the Employee list", ex);
  41.       throw new RuntimeException("Can't write the Employee list", ex);
  42.     }finally{
  43.       //This block explicitly closes only ps and does NOT close fos and bos.
  44.       //In usual case, closing ps also closes underlying fos and bos.
  45.       //But if exception occurrs at new PrintStream in try block,
  46.       //bos and fos may remain unclosed.
  47.       // -> UNSAFE
  48.  
  49.       if(ps != null){
  50.         try{ ps.close(); }
  51.         catch(Exception ex){ this.logger.error("Can't close a resource", ex); }
  52.       }
  53.     }
  54.   }
  55.  
  56.   public void writeEmployeesToFileAlsoUnsafe(@Nonnull List<Employee> emps, String path){
  57.  
  58.     PrintStream ps = null;
  59.  
  60.     try{
  61.       //may throw UnsupportedEncodingException
  62.       ps =  new PrintStream(new BufferedOutputStream(
  63.         new FileOutputStream(path), 1000), true, "utf-8");
  64.  
  65.       for(Employee emp : emps){
  66.         ps.println(emp.toString());
  67.       }
  68.     }catch(Exception ex){
  69.       this.logger.error("Can't write the Employee list", ex);
  70.       throw new RuntimeException("Can't write the Employee list", ex);
  71.     }finally{
  72.       //Same with right above case.
  73.       //When the exception occurs creating PrintStream after the underlying
  74.       //BufferedStream and FileOutputStream, the underlying streams would
  75.       //remain unclosed with the following code.
  76.       // -> UNSAFE
  77.  
  78.       if(ps != null){
  79.         try{ ps.close(); }
  80.         catch(Exception ex){ this.logger.error("Can't close a resource", ex); }
  81.       }
  82.     }
  83.   }
  84.  
  85.   public void writeEmployeesToFileSafe(@Nonnull List<Employee> emps, String path){ // method with SAFE codes
  86.  
  87.     //Define the resources as local variables as possible.
  88.     //Avoid to define them as member fields, without definite requirement.
  89.     //And do not handle these variables amongst multiple mehtod passing them.
  90.     //In other word, process all the necessary operations inside this method.
  91.     FileOutputStream fos = null;
  92.     BufferedOutputStream bos = null;
  93.     PrintStream ps = null;
  94.  
  95.     try{
  96.       //There a PrintStream(File) constructor which dosen't
  97.       //need to create underlying FileOutputStream or BufferedOutputStream.
  98.       //But, this sample dosen't use it to show the intended code pattern.
  99.  
  100.       fos = new FileOutputStream(path);
  101.       bos = new BufferedOutputStream(fos, 1000);
  102.       ps =  new PrintStream(bos, true, "utf-8"); //may throw UnsupportedEncodingException
  103.  
  104.       for(Employee emp : emps){
  105.         ps.println(emp.toString());
  106.       }
  107.  
  108.     }catch(Exception ex){
  109.       this.logger.error("Can't write the Employee list", ex);
  110.       throw new RuntimeException("Can't write the Employee list", ex);
  111.     }finally{
  112.       //take care of order - close the underlying reource first.
  113.       //take care of each try/catch pattern
  114.       // - close also can throw exception, but shouldn't block the next tries of close.
  115.  
  116.       if(fos != null){
  117.         try{ fos.close(); }
  118.         catch(Exception ex){ this.logger.error("Can't close a resource", ex); }
  119.       }
  120.       if(bos != null){
  121.         try{ bos.close(); }
  122.         catch(Exception ex){ this.logger.error("Can't close a resource", ex); }
  123.       }
  124.       if(ps != null){
  125.         try{ ps.close(); }
  126.         catch(Exception ex){ this.logger.error("Can't close a resource", ex); }
  127.       }
  128.     }
  129.   }


  • Sample 2 - java.sql package
  1. public List<Employee> listEmployees(@Nonnull List<String> ids){  // method with SAFE codes
  2.  
  3.   if(ids == null) throw new IllegalArgumentException("ID list should be specified.");
  4.  
  5.   Connection conn = null;
  6.   PreparedStatement ps = null;
  7.   ResultSet rs = null;
  8.  
  9.   List<Employee> result = new ArrayList<Employee>(ids.size());
  10.   String qry = "SELECT name, age, height, weight, married FROM emp WHERE id = ?";
  11.  
  12.   Employee emp = null;
  13.   try{
  14.     //In most cases, data-source manages connection pool internally.
  15.     conn = this.getDataSource().getConnection();
  16.     ps = conn.prepareStatement(qry);
  17.  
  18.     for(String id : ids){
  19.       ps.setString(1, id);
  20.       rs = ps.executeQuery();
  21.  
  22.       if(rs.next()){
  23.         emp = new Employee();
  24.         emp.setId(id);
  25.         emp.setAge(rs.getInt("age"));
  26.         emp.setHeight(rs.getDouble("height"));
  27.         emp.setWeight(rs.getDouble("weight"));
  28.         emp.setMarried(rs.getBoolean("married"));
  29.         result.add(emp);
  30.       }
  31.  
  32.       //Close each ResultSet in the iteration
  33.       //Although the spec says that closing of Statement can open only one
  34.       //ResultSet at a time and closing a Statement also close the ResultSet
  35.       //retunred by the Statement, you'd better not trust the implementations
  36.       //too much.  
  37.       if(rs != null){
  38.         try{ rs.close(); }
  39.         catch(Exception ex){ this.logger.error("Can't close ResultSet object", ex); }
  40.       }
  41.     }
  42.  
  43.   }catch(Exception ex){
  44.     this.logger.error("Can't list specified employees.", ex);
  45.     throw new RuntimeException("Can't list specified employees.", ex);
  46.   }finally{
  47.     //take care of order - reverse of creation order
  48.     //take care of each try/catch pattern
  49.     // - close also can throw exception, but shouldn't block the next lines.      
  50.  
  51.     if(rs != null){
  52.       try{ rs.close(); }
  53.       catch(Exception ex){ this.logger.error("Can't close ResultSet object", ex); }
  54.     }
  55.     if(ps != null){
  56.       try{ ps.close(); }
  57.       catch(Exception ex){ this.logger.error("Can't close PreparedStatement object", ex); }
  58.     }
  59.     if(conn != null){
  60.       try{ conn.close(); }
  61.       catch(Exception ex){ this.logger.error("Can't close Connection object", ex); }
  62.     }    
  63.   }
  64.   return result;
  65. }


  • Sample 3 - java.net package
  1.   //method with SAFE codes
  2.   /**
  3.    * Run this method in debug mode, and
  4.    * monitor the conn.connected field (which is protected)
  5.    * and the closed field of underlying input stream object.
  6.    */
  7.   @Test
  8.   public void testUrlConnection() throws Exception{
  9.  
  10.     // references
  11.     // http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html
  12.     // http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html
  13.     // http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html
  14.  
  15.     URL url = new URL("http://www.google.com/");
  16.     HttpURLConnection conn = null;
  17.     InputStreamReader isr = null;
  18.     BufferedReader br = null;
  19.  
  20.     try{
  21.       // "A new connection is opened every time by
  22.       // calling the openConnection method" - from Java SE API
  23.       conn = (HttpURLConnection)(url.openConnection());
  24.  
  25.       // "Operations that depend on being connected,
  26.       // like getContentLength, will implicitly perform
  27.       // the connection, if necessary."
  28.       // - from Java SE API
  29.       //
  30.       // "The connection is opened implicitly by calling
  31.       // getInputStream." - from The Java Tutorials
  32.       isr = new InputStreamReader(conn.getInputStream());
  33.       br = new BufferedReader(isr);
  34.  
  35.       String line;
  36.       while((line = br.readLine()) != null){
  37.         System.out.println(line);
  38.       }
  39.  
  40.     }catch(Exception ex){
  41.       throw ex;
  42.     }finally{
  43.  
  44.       if(conn != null){
  45.         try{ conn.disconnect(); }
  46.         catch(Exception ex){
  47.           this.logger.error("The connection is not diconnected.", ex);
  48.         }
  49.       }
  50.  
  51.       // "Invoking the close() methods on the InputStream or
  52.       // OutputStream of an URLConnection after a request may
  53.       // free network resources associated with this instance"
  54.       // - from Java SE API
  55.       if(isr != null){
  56.         try{ isr.close(); }
  57.         catch(Exception ex){
  58.           this.logger.error("The output stream is not closed.", ex);
  59.         }
  60.       }
  61.  
  62.       if(br != null){
  63.         try{ br.close(); }
  64.         catch(Exception ex){
  65.           this.logger.error("The output stream is not closed.", ex);
  66.         }
  67.       }
  68.     }
  69.   }


Investigating InitialContext using recursive call

You can get all name-class pairs under InitialContext of your application server using the following simple code containing recursive call.

  1. /**
  2.  * Retrieve all name class pairs recursively under the given naming context.
  3.  *
  4.  * @return
  5.  */
  6. public static Map<String, NameClassPair> getNameClassPairsUnderContext(String name, Context cntx) throws NamingException{
  7.  
  8.   if(cntx == null) throw new IllegalArgumentException("Context shouldn't be null.");
  9.    
  10.   Map<String, NameClassPair> result = new HashMap<String, NameClassPair>();
  11.   NamingEnumeration<NameClassPair> pairs = cntx.list("");
  12.   NameClassPair pair = null;
  13.   Object obj = null;
  14.   String path = null;
  15.   while(pairs.hasMore()){
  16.     pair = pairs.next();
  17.     obj = cntx.lookup(pair.getName());
  18.     path = name + "/" + pair.getName();
  19.      
  20.     if(obj instanceof javax.naming.Context){
  21.       result.put(path, pair);
  22.       result.putAll(getNameClassPairsUnderContext(path, (Context)obj));
  23.     }
  24.     else{ result.put(path, pair);}
  25.   }
  26.    
  27.   return result;
  28. }


Typical code pattern for Regex API

The simplest code pattern for when a regular expression is used just once is to use static Pattern.matches method.

  1. boolean b = Pattern.matches("a*b", "aaaaab");

When using a expression several times, it is better to use compiled pattern object considering performance.

  1. Pattern p = Pattern.compile("a*b");
  2. boolean b1 = p.matcher("aaaaab").matches();
  3. boolean b2 = p.matcher("bbbbb").matches();


Extract RGB pixel data in byte array from general image file

Note that java.awt.image.BufferedImage.getRGB(int, int, int, int, int[], int, int) method returns an array of integer pixels in the default RGB color model(TYPE_INT_ARGB) regardless of the intrinsic color model. Color conversion takes place if the intrinsic color model is not the default RGB.
By virtue of this automatic conversion inside BufferedImage when necessary, we can easily extract the RGB pixel data of the images in various formats (including those that don't uses RGB color space) using codes like following.

  1.    public static byte[] extractRgbPixelsFromImage(String path) throws IOException{
  2.  
  3.       BufferedImage img = ImageIO.read(new File(path));
  4.       int w = img.getWidth();
  5.       int h = img.getHeight();
  6.       int[] pixels = null;
  7.  
  8.       pixels = img.getRGB(0, 0, w, h, null, 0, w); //ARGB pixels (regardless of original color model and color space)
  9.  
  10.       byte[] bytes = new byte[w * h * 3];
  11.       int pixel = 0;
  12.       for(int i = 0; i < w * h; i++){
  13.          pixel = pixels[i];
  14.          bytes[i * 3 + 0] = (byte)(pixel >> 16 & 0xff);
  15.          bytes[i * 3 + 1] = (byte)(pixel >> 8 & 0xff);
  16.          bytes[i * 3 + 2] = (byte)(pixel & 0xff);
  17.       }
  18.  
  19.       return bytes;
  20.    }

References

Typical usage pattern of SLF4J Logger

The following code snippet is from the API documentation of SLF4J Logger interface. Note that they recommend the logger to be final static member of the user class.

  1.  import org.slf4j.Logger;
  2.  import org.slf4j.LoggerFactory;
  3.  
  4.  public class Wombat {
  5.  
  6.    final static Logger logger = LoggerFactory.getLogger(Wombat.class);
  7.    Integer t;
  8.    Integer oldT;
  9.  
  10.    public void setTemperature(Integer temperature) {
  11.      oldT = t;
  12.      t = temperature;
  13.      logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
  14.      if(temperature.intValue() > 50) {
  15.        logger.info("Temperature has risen above 50 degrees.");
  16.      }
  17.    }
  18.  }

Simplest Log4j configuration

Properties configuration

  • Properties configurations support DailyRollingFileAppender, but don't support TimeBasedRollingPolicy and RollingFileAppender.
  1. # Pre-defined appender can be customized using Java system properties : Console, DRFA
  2.  
  3. # ext properties are expected to be specified as Java system properties in command-line
  4. ext.log.dir=${user.home}
  5. ext.log.file=log4j.log
  6.  
  7. # global settings
  8. log4j.rootLogger=INFO,Console,DRFA
  9. log4j.threshhold=ALL
  10.  
  11. # Console appender
  12. log4j.appender.Console=org.apache.log4j.ConsoleAppender
  13. log4j.appender.Console.Target=System.out
  14. log4j.appender.Console.Threshold=WARN
  15. log4j.appender.Console.layout=org.apache.log4j.PatternLayout
  16. log4j.appender.Console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %-5p %c{2}: %m%n
  17.  
  18. # Pre-defined daily rolling file appender
  19. log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
  20. log4j.appender.DRFA.Threshold=DEBUG
  21. log4j.appender.DRFA.File=${ext.log.dir}/${ext.log.file}
  22. log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
  23. log4j.appender.DRFA.MaxBackupIndex=30
  24. log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
  25. log4j.appender.DRFA.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %-5p %c{2} (%F:%M(%L)) - %m%n

XML configuration

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE log4j:configuration>
  3.  
  4. <log4j:configuration debug="true" threshold="all" xmlns:log4j="http://jakarta.apache.org/log4j/">
  5.   <root>
  6.     <priority value="DEBUG" />
  7.     <appender-ref ref="Console" />
  8.     <appender-ref ref="DRFA" />
  9.   </root>
  10.  
  11.   <appender name="Console" class="org.apache.log4j.ConsoleAppender">
  12.     <param name="Target" value="System.out" />
  13.     <param name="Threshold" value="TRACE" />
  14.     <layout class="org.apache.log4j.PatternLayout">
  15.       <param name="ConversionPattern" value="[%d{yy/MM/dd,HH:mm:ss}|%-5p|%c{2}] %m(%M{1}:%L)" />
  16.     </layout>
  17.   </appender>
  18.  
  19.   <appender name="DRFA" class="org.apache.log4j.rolling.RollingFileAppender">
  20.     <param name="MaxBackupIndex" value="30" />
  21.     <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
  22.       <param name="FileNamePattern" value="${LOG_FILE_DIR}\\log4j.%d{yyyy-MM-dd}.log" />
  23.     </rollingPolicy>
  24.     <layout class="org.apache.log4j.PatternLayout">
  25.       <param name="ConversionPattern" value="[%d{yy/MM/dd,HH:mm:ss}|%-5p|%c{2}] %m(%M{1}:%L)%n" />
  26.     </layout>
  27.   </appender>
  28.  
  29. </log4j:configuration>

Simplest Logback configuration

  1. <?xml version="1.0"?>
  2. <configuration debug="true" scan="true" scanPeriod="180 seconds">
  3.  
  4.    <!-- For more on JMX configuration, refer http://logback.qos.ch/manual/jmxConfig.html -->
  5.    <jmxConfigurator/>
  6.  
  7.    <property name="_LOG_FILE_DIR" value="${log.file.dir:-${LOG_BASE:-${TEMP:-${user.home}}}}" />
  8.    <property name="_LOG_FILE_NAME" value="${log.file.name:-logback}" /> <!-- excluding path and extension -->
  9.    <property name="_LOG_TIMEZONE" value="${log.timezone:-Asia/Seoul}"/>
  10.    <property name="_LOG_PID" value="${log.pid:-false}" />
  11.    <property name="_LOG_LEVEL_ROOT" value="${log.level.root:-${log.level.default:-INFO}}"/>
  12.    <property name="_LOG_LEVEL_SPRING" value="${log.level.spring:-${log.level.default:-INFO}}"/>
  13.    <property name="_LOG_LEVEL_MYBATIS" value="${log.level.mybatis:-${log.level.default:-INFO}}"/>
  14.    <property name="_LOG_LEVEL_JETTY" value="${log.level.jetty:-${log.level.default:-DEBUG}}" />
  15.    <property name="_LOG_LEVEL_AKKA" value="${log.level.akka:-${log.level.default:-DEBUG}}" />
  16.    <property name="_LOG_LEVEL_AKKA_CLUSTER_HEARTBEAT" value="${log.level.akka.clusterHeartBeat:-OFF}"/>
  17.  
  18.    <if condition='property("_LOG_PID").trim().equals("true")'>
  19.       <then>
  20.          <!-- For more on conversion pattern, refer http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout -->
  21.          <property name="_PATTERN_HEADER" value="[%d{yy/MM/dd HH:mm:ss, ${_LOG_TIMEZONE}}|%-5.-5p|%X{pid}|%-15.-15t|%40.40c{2}]" />
  22.          <!-- %M is not particularly fast. Thus, it should be uses only in test -->
  23.          <property name="_PATTERN_HEADER_METHOD" value="[%d{yy/MM/dd HH:mm:ss, ${_LOG_TIMEZONE}}|%-5.-5p|%X{pid}|%-15.-15t|%40.40c{2}|%M]" />
  24.       </then>
  25.       <else>
  26.          <property name="_PATTERN_HEADER" value="[%d{yy/MM/dd HH:mm:ss, ${_LOG_TIMEZONE}}|%-5.-5p|%-15.-15t|%40.40c{2}]" />
  27.          <property name="_PATTERN_HEADER_METHOD" value="[%d{yy/MM/dd HH:mm:ss, ${_LOG_TIMEZONE}}|%-5.-5p|%-15.-15t|%40.40c{2}|%M]" />
  28.       </else>
  29.    </if>
  30.  
  31.    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
  32.       <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  33.          <level>DEBUG</level>
  34.       </filter>
  35.       <encoder>
  36.          <pattern>${_PATTERN_HEADER} %m%n</pattern>
  37.       </encoder>
  38.    </appender>
  39.    <!-- For more on RollingFileAppender, refer http://logback.qos.ch/manual/appenders.html#RollingFileAppender -->
  40.    <appender name="DRFA" class="ch.qos.logback.core.rolling.RollingFileAppender">
  41.       <!-- Do NOT specify file element to use prudent mode -->
  42.       <prudent>true</prudent>
  43.       <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  44.          <fileNamePattern>${_LOG_FILE_DIR}/${_LOG_FILE_NAME}.%d{yyyy-MM-dd, ${_LOG_TIMEZONE}}.log</fileNamePattern>
  45.          <maxHistory>10</maxHistory>
  46.       </rollingPolicy>
  47.       <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  48.          <level>DEBUG</level>
  49.       </filter>
  50.       <encoder>
  51.          <pattern>${_PATTERN_HEADER} %m%n</pattern>
  52.       </encoder>
  53.    </appender>
  54.  
  55.    <root level="${_LOG_LEVEL_ROOT}">
  56.       <appender-ref ref="Console" />
  57.       <appender-ref ref="DRFA" />
  58.    </root>
  59.  
  60.    <logger name="org.springframework" level="${_LOG_LEVEL_SPRING}" additivity="false">
  61.       <appender-ref ref="Console" />
  62.       <appender-ref ref="DRFA" />
  63.    </logger>
  64.  
  65.    <logger name="org.apache.ibatis" level="${_LOG_LEVEL_MYBATIS}" additivity="false">
  66.       <appender-ref ref="Console" />
  67.       <appender-ref ref="DRFA" />
  68.    </logger>
  69.  
  70.   <logger name="org.mybatis.spring" level="${_LOG_LEVEL_MYBATIS}" additivity="false">
  71.       <appender-ref ref="Console" />
  72.       <appender-ref ref="DRFA" />
  73.    </logger>
  74.  
  75.    <logger name="org.eclipse.jetty" level="${_LOG_LEVEL_JETTY}" additivity="false">
  76.       <appender-ref ref="Console" />
  77.       <appender-ref ref="DRFA" />
  78.    </logger>
  79.  
  80.    <logger name="org.eclipse.jetty.http.HttpParser" level="${_LOG_LEVEL_JETTY}" additivity="false">
  81.       <appender-ref ref="DRFA" />
  82.    </logger>
  83.  
  84.    <logger name="org.eclipse.jetty.webapp.WebAppClassLoader" level="${_LOG_LEVEL_JETTY}" additivity="false">
  85.       <appender-ref ref="DRFA" />
  86.    </logger>
  87.  
  88.    <logger name="akka" level="${_LOG_LEVEL_AKKA}" additivity="false">
  89.       <appender-ref ref="Console" />
  90.       <appender-ref ref="DRFA" />
  91.    </logger>
  92.  
  93.    <logger name="akka.cluster.ClusterHeartbeatSender" level="${_LOG_LEVEL_AKKA_CLUSTER_HEARTBEAT}" additivity="false">
  94.       <appender-ref ref="DRFA" />
  95.    </logger>
  96. </configuration>

Identifying the implementation of JAXP in use

      System.out.printf("%1$s = %2$s\n",
            "javax.xml.parsers.SAXParserFactory", System.getProperty("javax.xml.parsers.SAXParserFactory"));
      System.out.printf("%1$s = %2$s\n",
            "javax.xml.parsers.DocumentBuilderFactory", System.getProperty("javax.xml.parsers.DocumentBuilderFactory"));
      System.out.printf("%1$s = %2$s\n",
            "javax.xml.transform.TransformerFactory", System.getProperty("javax.xml.transform.TransformerFactory"));
      System.out.printf("%1$s = %2$s\n",
            "javax.xml.xpath.XPathFactory", System.getProperty("javax.xml.xpath.XPathFactory"));
      System.out.printf("%1$s = %2$s\n",
            "javax.xml.validation.SchemaFactory", System.getProperty("javax.xml.validation.SchemaFactory"));      

      System.out.printf("SaxParserFactory implementation = %1$s\n",
            SAXParserFactory.newInstance().getClass().getName());
      System.out.printf("DocumentBuilderFactory implementation = %1$s\n",
            DocumentBuilderFactory.newInstance().getClass().getName());
      System.out.printf("TransformerFactory implementation = %1$s\n",
            TransformerFactory.newInstance().getClass().getName());
      System.out.printf("XPathFactory implementation = %1$s\n",
            XPathFactory.newInstance().getClass().getName());
      System.out.printf("SchemaFactory implementation = %1$s\n",
            SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).getClass().getName());


Validating XML document using DTD, XML Schema, RELAX NG or Schematron

As of Java SE 1.5, javax.xml.validation package is added. It makes the validation of XML using various schema language more clear and convenient.

Validating with DOM praser explicitly

The following code snippet is a little bit enhancement of the one from the API documentation of javax.xml.validation package.

  1.     DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
  2.     builderFactory.setNamespaceAware(true);
  3.     builderFactory.setValidating(false);
  4.  
  5.     // parse an XML document into a DOM tree
  6.     DocumentBuilder parser = builderFactory .newDocumentBuilder();
  7.     Document document = parser.parse(new File("instance.xml"));
  8.  
  9.     // create a SchemaFactory capable of understanding WXS schemas
  10.     SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  11.  
  12.     // load a WXS schema, represented by a Schema instance
  13.     Source schemaFile = new StreamSource(new File("mySchema.xsd"));
  14.     Schema schema = factory.newSchema(schemaFile);
  15.  
  16.     // create a Validator instance, which can be used to validate an instance document
  17.     Validator validator = schema.newValidator();
  18.  
  19.     // validate the DOM tree
  20.     try {
  21.         validator.validate(new DOMSource(document));
  22.     } catch (SAXException e) {
  23.         // instance document is invalid!
  24.     }

Validating without parser explicitly

When using DOM parser, the exact location of invalid element is difficulty to get. To get exact location, you should use SAX parser or stream parser. When using stream parser, you may not create explicitly stream parser in your code. Instead, just use

StreamSource.

  1.     ...
  2.     URL schUrl = ClassLoader.getSystemResource("component-meta.xsd");
  3.     URL xmlUrl = ClassLoader.getSystemResource("component-meta-valid.xml");
  4.    
  5.     SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  6.     //A Schema object is thread safe and applications are encouraged to share it across many parsers in many threads.
  7.     Schema sch = sf.newSchema(new java.io.File(schUrl.toURI()));
  8.     //A validator object is not thread-safe and not reentrant.
  9.     Validator vldt = sch.newValidator();
  10.    
  11.     SimpleCollectiveErrorHandler errHandler = new SimpleCollectiveErrorHandler();
  12.     vldt.setErrorHandler(errHandler);
  13.     vldt.validate(new StreamSource(new java.io.File(xmlUrl.toURI())));
  14.    
  15.     List<SAXParseException> errors = errHandler.getErrors();
  16.    
  17.     System.err.println("There exist " + errors.size() + " errors.");
  18.     for(SAXParseException error : errors){
  19.       SimpleCollectiveErrorHandler.printSAXParseException(System.err, error);
  20.     }
  21.  
  22.     ....

Error Handler

In the above code, a custom ErrorHandler is used. The error handler classes provided by JDK is somewhat simple. The source of the custom error handler ('SimpleCollectiveErrorHandler') is like as below.

  1. public class SimpleCollectiveErrorHandler extends DefaultHandler{
  2.  
  3.   private List<SAXParseException> errors = new java.util.ArrayList<SAXParseException>();
  4.  
  5.   public List<SAXParseException> getErrors(){ return this.errors; }
  6.  
  7.   public boolean hasError(){ return !this.errors.isEmpty(); }
  8.  
  9.   @Override public void warning(SAXParseException ex){}
  10.   @Override public void error(SAXParseException ex){ this.errors.add(ex); }
  11.   @Override public void fatalError(SAXParseException ex){ this.errors.add(ex); }
  12.  
  13.   public void printErrors(PrintStream ps){
  14.     if(ps == null) return;
  15.     ps.println(">> Errors : " + this.errors.size());
  16.     for(SAXParseException ex: this.errors)    printSAXParseException(ps, ex);
  17.     ps.println("");
  18.   }
  19.  
  20.   public static void printSAXParseException(PrintStream ps, SAXParseException ex){
  21.     ps.println("Line : " + ex.getLineNumber() + ", Column : " + ex.getColumnNumber() + " ; " + ex.getMessage());
  22.   }
  23. }

Validating XML document with no declared namespace using schema

When validating XML documents with no namespace related attributes such as xmlns or xsi:noNamespaceSchemaLocation in the root element, Applying schema with xmlns or targetNamespace would cause fundamental errors that say's "Cannot find the declaration of element ...".

To successfully apply the schema without the modification (such as adding xmlns attribute.) of XML documents, the schema to apply should not have xmlns and targetNamespace attributes.

  • XLM document to validate
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <component-meta>
  4.   <name>pie-chart</name>
  5.   <ver>1.0</ver>
  6.   <parts>
  7.     <part>
  8.       <name>pie</name>
  9.       <properties>
  10.         <property>
  11.           <name>title</name>
  12.           ...
  • Schema to use
  1. <xsd:schema
  2.  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  3.  elementFormDefault="qualified">
  4.  
  5. <xsd:annotation>
  6.   <xsd:documentation>
  7. adding the following attribute to the schema element will prevent
  8. applying this schema to the document without namespace declarations
  9. using xmlns or xsi:noNamespaceSchemaLocation attribute
  10.  
  11.   xmlns="http://www.3rdstage.org/schema/component-meta"
  12.   targetNamespace="http://www.3rdstage.org/schema/component-meta"
  13.   </xsd:documentation>
  14. </xsd:annotation>
  15.  
  16. <xsd:element name="component-meta" type="component-metaType"/>
  17.  
  18. <xsd:complexType name="component-metaType">
  19.   <xsd:sequence>
  20.     <xsd:element name="name">
  21.       <xsd:simpleType>
  22.         <xsd:restriction base="xsd:string">
  23.           <xsd:pattern value="[a-zA-Z][-_:.0-9a-zA-Z]*"/>
  24.         </xsd:restriction>
  25.       </xsd:simpleType>
  26.     </xsd:element>
  27. ...


Access XML using XPath and DOM

Maybe, the most common use case of XPath would be along with DOM representation of XML. The following sample is provided in the API documentation of javax.xml.xpath package.
Note that XPathFactory and XPath class is NOT expected to be thread-safe, says the API documentation.

  1. // parse the XML as a W3C Document
  2. DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
  3. Document document = builder.parse(new File("/widgets.xml"));
  4.  
  5. XPath xpath = XPathFactory.newInstance().newXPath();
  6. String expression = "/widgets/widget";
  7. Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);


Applying XQuery on HTML

Saxon can't parse HTML file directly. But using TagSoup along with Saxon, you can parse HTML and apply XPath or XQuery to access data. The sample below shows the overall programming.

  1. package thirdstage.exercise.xml.saxon;
  2.  
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.net.URL;
  6.  
  7. import javax.xml.parsers.DocumentBuilder;
  8. import javax.xml.transform.Source;
  9. import javax.xml.transform.dom.DOMSource;
  10. import javax.xml.transform.sax.SAXSource;
  11.  
  12. import net.sf.saxon.Configuration;
  13. import net.sf.saxon.dom.DocumentBuilderImpl;
  14. import net.sf.saxon.lib.ParseOptions;
  15. import net.sf.saxon.lib.Validation;
  16. import net.sf.saxon.s9api.Processor;
  17. import net.sf.saxon.s9api.XQueryCompiler;
  18. import net.sf.saxon.s9api.XQueryEvaluator;
  19. import net.sf.saxon.s9api.XQueryExecutable;
  20. import net.sf.saxon.s9api.XdmNode;
  21. import net.sf.saxon.s9api.XdmValue;
  22.  
  23. import org.ccil.cowan.tagsoup.Parser;
  24. import org.testng.annotations.Test;
  25. import org.w3c.dom.Document;
  26. import org.xml.sax.InputSource;
  27. import org.xml.sax.XMLReader;
  28.  
  29. ...
  30.  
  31.   @Test
  32.   public void testXqueryOnHtmlAlongWithTagSoup() throws Exception{
  33.  
  34.     Configuration cfg = new Configuration();
  35.     cfg.setSchemaValidationMode(Validation.LAX);
  36.     cfg.setValidation(false);
  37.     cfg.setValidationWarnings(true);
  38.     Processor proc = new Processor(cfg);
  39.  
  40.     URL url = ClassLoader.getSystemResource("thirdstage/exercise/xml/saxon/krx-stock-code-only-10.html");
  41.     XMLReader xr = new org.ccil.cowan.tagsoup.Parser();
  42.     //xr.setFeature(Parser.namespacesFeature, false);
  43.     Source src = new SAXSource(xr, new InputSource(new FileInputStream(new File(url.toURI()))));
  44.     net.sf.saxon.s9api.DocumentBuilder db = proc.newDocumentBuilder();
  45.     XdmNode input = db.build(src);
  46.  
  47.     String qr = new StringBuilder()
  48.       .append("declare default element namespace \"http://www.w3.org/1999/xhtml\";\n")
  49.       .append("for $x in /html/body[1]/table[1]/tr/td[1]/child::text() return $x").toString();
  50.     XQueryCompiler xqc = proc.newXQueryCompiler();
  51.     XQueryExecutable xqe = xqc.compile(qr);
  52.     XQueryEvaluator xqev = xqe.load();
  53.     xqev.setSource(input.asSource());
  54.  
  55.     XdmValue result = xqev.evaluate();
  56.  
  57.     System.out.printf("The result of query contains %1$d items.\n", result.size());
  58.     System.out.printf(result.toString());
  59.   }
  60.  
  61. ...


Marshalling or Unmarshalling XML using JAXB

The main entrance class of JAXB is javax.xml.bind.JAXBContext. Typically, JAXBContext object is created on the behalf of context object(s) and then, marshaller, unmarshaller and validator can be obtained from the context.

Typical code sample from the API document is as following

   JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );

   // unmarshal from foo.xml
   Unmarshaller u = jc.createUnmarshaller();
   FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) );

   // marshal to System.out
   Marshaller m = jc.createMarshaller();
   m.marshal( fooObj, System.out );

API documentation of Marshaller and Unmarshaller has more sample codes in various circumstances.


Serialize objects into JSON strings using Jackson and JAXB annotations

   private final List<MessierObject> messierCatalog = new ArrayList<MessierObject>();

   private static final ObjectMapper jacksonMapper = new ObjectMapper();

   static{
      jacksonMapper.registerModule(new JaxbAnnotationModule())
      .configure(MapperFeature.AUTO_DETECT_FIELDS, false)
      .configure(MapperFeature.AUTO_DETECT_CREATORS, false)
      .configure(MapperFeature.AUTO_DETECT_GETTERS, true)
      .configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true)
      .configure(MapperFeature.AUTO_DETECT_SETTERS, true);
   }

   @Nonnull
   public List<MessierObject> getMessierCatalog(){
      return this.messierCatalog;
   }

   public String getMessierCatalogInJsonString() throws Exception{
      String result = null;

      List<MessierObject> mos = this.getMessierCatalog();

      Writer wr = new StringWriter();
      jacksonMapper.writeValue(wr, mos);

      return wr.toString();
   }

   @Immutable
   public static class MessierObject{

      private String number;

      private String ngcNumber;

      private String commonName;

      private String type;

      private Double distance;

      private String constellation;

      private Double apparentMagnitude;

      /**
       * @param number
       * @param ngcNumber
       * @param commonName
       * @param type
       * @param distance
       * @param constellation
       * @param apparentMagnitude
       */
      @JsonCreator
      public MessierObject(@JsonProperty("number") String number,
            @JsonProperty("ngc-number") String ngcNumber,
            @JsonProperty("common-name") String commonName,
            @JsonProperty("type") String type,
            @JsonProperty("distance") Double distance,
            @JsonProperty("constellation") String constellation,
            @JsonProperty("apparent-magnitude") Double apparentMagnitude){
         super();
         this.number = number;
         this.ngcNumber = ngcNumber;
         this.commonName = commonName;
         this.type = type;
         this.distance = distance;
         this.constellation = constellation;
         this.apparentMagnitude = apparentMagnitude;
      }

      public String getNumber(){ return number; }

      public String getNgcNumber(){ return ngcNumber;}

      public String getCommonName(){ return commonName; }

      public String getType(){ return type; }

      public Double getDistance(){ return distance; }

      public String getConstellation(){ return constellation; }

      public Double getApparentMagnitude(){ return apparentMagnitude; }
   }

Loading FreeMarker template using classpath resource

Locating resources as a classpath resource is very useful, 'cause it makes the code more portable. When loading template files for FreeMarker, you can set the ClassTemplateLoader as a TemplateLoader using code like the following.

In the following code, the Schedule.ftl is expected to be located in some foo/bar directory under the root directories of classpath. But it's not clear, whether the template can be loaded when the file is in the archived file or not.

  1. ...
  2. import freemarker.template.Configuration;
  3. import freemarker.template.Template;
  4. ...
  5.  
  6.   //context or configuration for the FreeMaker, thread-safe without modification after initiation.
  7.   Configuration config = new Configuration();
  8.   config.setWhitespaceStripping(true);
  9.   config.setClassForTemplateLoading(this.getClass(), "/");
  10.   BeansWrapper bw = new BeansWrapper();
  11.   bw.setExposeFields(true);
  12.   config.setObjectWrapper(bw);
  13.  
  14.   //set static methods and enums as shared variables.
  15.   config.setSharedVariable("statics", BeansWrapper.getDefaultInstance().getStaticModels());
  16.   config.setSharedVariable("enums", BeansWrapper.getDefaultInstance().getEnumModels());
  17.  
  18.   //template, NOT thread-safe
  19.   Template tpl = config.getTemplate("foo/bar/Schedule.ftl");
  20.   StringWriter sw = new StringWriter();
  21.  
  22.   tpl.process(schedule, sw);
  23.   String result = sw.toString();
  24.  
  25. ...

AOP

Sample Aspect to trace method call on RTMPMinaIoHandler in Red5 client

  • Red5 client is highly concurrent using Apache MINA. So, tracing internal run-time behavior of it is not so trivial. Using AOP can be a little bit better approach.
import javax.annotation.Nonnull;

import org.aspectj.lang.JoinPoint.EnclosingStaticPart;
import org.aspectj.lang.JoinPoint.StaticPart;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoSession;
import org.red5.client.net.rtmp.RTMPMinaIoHandler;

/**
 * @author Sangmoon Oh
 * @since 2015-07-21
 */

@Aspect
public class Red5RtmpClientTracingAspect {

  private transient final Logger logger = LoggerFactory.getLogger(this.getClass());

  public final static Marker AOP_MARKER = MarkerFactory.getMarker("AOP");

  /**
   * Traces {@code sessionCreated}, {@code sessionOpened}, {@code sessionClosed}
   * of {@code RTMPMinaIoHandler}.
   *
   * @param joinPt
   * @param enclosingJoinPt
   * @param sess
   * @param msg
   * @see org.red5.client.net.rtmp.RTMPMinaIoHandler#sessionCreated(IoSession)
   * @see org.red5.client.net.rtmp.RTMPMinaIoHandler#sessionOpened(IoSession)
   * @see org.red5.client.net.rtmp.RTMPMinaIoHandler#sessionClosed(IoSession)
   */

  @Before("call(public void IoHandler.message*(..)) && target(RTMPMinaIoHandler) && args(sess, msg)")
  public void beforeCallMinaIoHandlerMessageMethods(final StaticPart joinPt,
    final EnclosingStaticPart enclosingJoinPt, IoSession sess, Object msg){
    Pair<String, String> fromTo = this.getFromToMethods(joinPt, enclosingJoinPt);

    logger.debug(AOP_MARKER, "Method Call: {} -> {}, Session ID: {}, Message Type: {}",
        fromTo.getLeft(), fromTo.getRight(), (sess != null) ? sess.getId() : "",
        (msg != null) ? msg.getClass().getSimpleName() : "null");
  }

  /**
   * Traces {@code messageReceived} and {@code messageSent} methods of
   * {@code RTMPMinaIoHandler} class.
   *
   * @param joinPt
   * @param enclosingJoinPt
   * @param sess
   * @see org.red5.client.net.rtmp.RTMPMinaIoHandler#messageReceived(IoSession, Object)
   * @see org.red5.client.net.rtmp.RTMPMinaIoHandler#messageSent(IoSession, Object)
   */

  @Before("call(public void IoHandler.session*(..)) && target(RTMPMinaIoHandler) && args(sess)")
  public void beforeCallMinaIoHandlerSessionMethods(final StaticPart joinPt,
    final EnclosingStaticPart enclosingJoinPt, IoSession sess){
    Pair<String, String> fromTo = this.getFromToMethods(joinPt, enclosingJoinPt);

    logger.debug(AOP_MARKER, "Method Call: {} -> {}, Session ID: {}",
        fromTo.getLeft(), fromTo.getRight(), (sess != null) ? sess.getId() : "");
  }

  @Nonnull
  private Pair<String, String> getFromToMethods(@Nonnull StaticPart joinPt, @Nonnull EnclosingStaticPart enclosingJoinPt){
    String from = enclosingJoinPt.getSignature().getDeclaringType().getSimpleName() + "."
        + enclosingJoinPt.getSignature().getName();
    String to = joinPt.getSignature().getDeclaringType().getSimpleName() + "."
        + joinPt.getSignature().getName();

    return Pair.of(from, to);
  }
}

aop.xml for this Aspect is

<aspectj>
   <weaver options="-showWeaveInfo">
      <include within="org.red5..*" />
      <include within="org.apache.mina..*"/>
   </weaver>

   <aspects>
      <aspect name="...Red5RtmpClientTracingAspect" />
   </aspects>
</aspectj>

Java EE

Samples of deployment descriptors

web.xml of Servlet 2.5

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
 version="2.5">
  <display-name>A Simple Application</display-name>
  <context-param>
    <param-name>Webmaster</param-name>
    <param-value>webmaster@mycorp.com</param-value>
  </context-param>
  <servlet>
    <servlet-name>catalog</servlet-name>
    <servlet-class>com.mycorp.CatalogServlet
    </servlet-class>
    <init-param>
      <param-name>catalog</param-name>
      <param-value>Spring</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>catalog</servlet-name>
    <url-pattern>/catalog/*</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
  <mime-mapping>
    <extension>pdf</extension>
    <mime-type>application/pdf</mime-type>
  </mime-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
  </welcome-file-list>
  <error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
  </error-page>
</web-app>

Spring Framework

BeanFactory and ApplicationContext types

Boilerplate for Spring configuration

spring-base.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
  4.  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
  5.  xmlns:lang="http://www.springframework.org/schema/lang" xmlns:util="http://www.springframework.org/schema/util"
  6.  xsi:schemaLocation="
  7.      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8.      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
  9.      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  10.      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
  11.      http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
  12.      http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
  13.      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
  14.  
  15.   <description>
  16.     Spring container configuration
  17.   </description>
  18.  
  19.    <!-- @TODO Use SpEL to be able to specify custom property files using System Property -->
  20.   <util:properties id="config" location="classpath:.../.../.../config.properties" />
  21.    <!-- For more on property-placeholder, refer https://github.com/spring-projects/spring-framework/blob/4.0.x/spring-context/src/main/resources/org/springframework/context/config/spring-context-4.0.xsd#L22 -->
  22.   <context:property-placeholder properties-ref="config"
  23.    system-properties-mode="ENVIRONMENT" local-override="false" ignore-unresolvable="true" />
  24.  
  25.    <!-- enabling Auto-wiring -->
  26.   <context:annotation-config>
  27.     <description>Activates various annotations to be detected in bean classes such
  28.       as @Required, @Autowired, @Resource or et. al.
  29.     </description>
  30.   </context:annotation-config>
  31.  
  32.    <!-- enabling Auto-registering -->
  33.    <!-- @Note Do NOT use auto-registering of Spring beans as possible.
  34.   <context:component-scan base-package=""/>
  35.   -->
  36.  
  37.    <!-- enabling LTW of AspectJ -->
  38.    <!-- @Note Use compile-time weaving as possible.
  39.   <context:load-time-weaver/>
  40.   -->
  41.  
  42.    <!-- enabling @Async, @Scheduled ... -->
  43.    <!-- For more, refer http://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/scheduling.html -->
  44.   <task:annotation-driven />
  45.  
  46.   <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
  47.     <property name="locateExistingServerIfPossible" value="true" />
  48.   </bean>
  49.  
  50.    <!-- Data access and transaction -->
  51.    <!-- @TODO Add alternative usage of DBCP 1.4 in case of Java SE 1.6 -->
  52.   <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
  53.     <description>
  54.       https://commons.apache.org/proper/commons-dbcp/api-2.1/org/apache/commons/dbcp2/BasicDataSource.html
  55.     </description>
  56.     <property name="jmxName" value="${jmx.domain}:type=fabric,name=dataSource" />
  57.     <property name="driverClassName" value="${datasource.jdbcDriver}" />
  58.     <property name="url" value="${datasource.jdbcUrl}" />
  59.     <property name="username" value="${datasource.user}" />
  60.     <property name="password" value="${datasource.password}" />
  61.     <property name="defaultAutoCommit" value="true" />
  62.     <property name="maxTotal" value="${datasource.maxTotal}" />
  63.     <property name="maxIdle" value="${datasource.maxIdle}" />
  64.     <property name="minIdle" value="${datasource.minIdle}" />
  65.     <property name="initialSize" value="${datasource.initSize}" />
  66.   </bean>
  67.  
  68.   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  69.     <description>
  70.       http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/jdbc/datasource/DataSourceTransactionManager.html
  71.       http://mybatis.github.io/spring/transactions.html
  72.       Included in spring-jdbc artifact
  73.     </description>
  74.     <property name="dataSource" ref="dataSource" />
  75.     <property name="defaultTimeout" value="120" />
  76.     <property name="nestedTransactionAllowed" value="false" /> <!-- default is true -->
  77.   </bean>
  78.  
  79.    <!-- @Note Use 'aspectj' mode as possible to enable in-class call and private methods with @Transactional -->
  80.    <!-- For more on @Transactional in 'aspectj' mode, refer https://gerrydevstory.com/2014/06/28/spring-declarative-transaction-management-with-jdk-proxy-vs-aspectj -->
  81.   <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"
  82.    proxy-target-class="true" />
  83.  
  84.   <bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">
  85.     <description>
  86.       DatabaseIdProvider should be set to SqlSessionFactory directly by setDatabaseIdProvider.
  87.       The databaseIdProvider element in the configuration XML will be ignored when the XML is set to
  88.       SqlSessionFactory.
  89.  
  90.       http://mybatis.github.io/spring/factorybean.html#Properties
  91.       http://mybatis.github.io/mybatis-3/apidocs/reference/org/apache/ibatis/mapping/VendorDatabaseIdProvider.html
  92.     </description>
  93.     <property name="properties">
  94.       <props>
  95.         <prop key="Microsoft SQL Server">ms</prop>
  96.         <prop key="Oracle">oracle</prop>
  97.         <prop key="MySQL">mysql</prop>
  98.       </props>
  99.     </property>
  100.   </bean>
  101.  
  102.   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  103.     <description>
  104.       http://mybatis.github.io/spring/factorybean.html
  105.       http://mybatis.github.io/spring/apidocs/reference/org/mybatis/spring/SqlSessionFactoryBean.html
  106.     </description>
  107.     <property name="dataSource" ref="dataSource" />
  108.     <property name="configLocation" value="${mybatis.configLocation}" />
  109.     <property name="databaseIdProvider" ref="databaseIdProvider" />
  110.   </bean>
  111.  
  112.    <!-- Scanner for Mybatis SQL Mappers -->
  113.   <bean id="sqlMapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  114.     <description>
  115.       http://mybatis.github.io/spring/apidocs/reference/org/mybatis/spring/mapper/MapperScannerConfigurer.html
  116.       This class seems to have problem when using with placeholder.
  117.     </description>
  118.     <property name="processPropertyPlaceHolders" value="true" />
  119.     <property name="basePackage" value="${mybatis.mappers.basePackage}" />
  120.     <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
  121.     <property name="annotationClass" value="org.springframework.stereotype.Repository" />
  122.   </bean>
  123.  
  124.    <!-- JXM -->
  125.   <beans profile="!production">
  126.     <description>JMX configuration - to disable JMX, use '-Dspring.profiles.active=production'</description>
  127.     <bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
  128.  
  129.     <bean id="manualJmxExporter" class="org.springframework.jmx.export.MBeanExporter"
  130.      lazy-init="false">
  131.       <description>
  132.         http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/jmx/export/MBeanExporter.html
  133.       </description>
  134.       <property name="beans">
  135.         <map>
  136.           <entry key="${jmx.domain}:type=fabric,name=transactionManager" value-ref="transactionManager" />
  137.           <entry key="${jmx.domain}:type=fabric,name=databaseIdProvider" value-ref="databaseIdProvider" />
  138.           <entry key="${jmx.domain}:type=fabric,name=sqlSessionFactory" value-ref="sqlSessionFactory" />
  139.           <entry key="${jmx.domain}:type=fabric,name=sqlMapperScanner" value-ref="sqlMapperScanner" />
  140.         </map>
  141.       </property>
  142.       <property name="server" ref="mbeanServer" />
  143.     </bean>
  144.  
  145.     <bean id="autodetectJmxExporter" class="org.springframework.jmx.export.MBeanExporter"
  146.      lazy-init="false">
  147.       <property name="assembler">
  148.         <bean class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
  149.           <property name="attributeSource" ref="jmxAttributeSource" />
  150.         </bean>
  151.       </property>
  152.       <property name="namingStrategy">
  153.         <bean class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
  154.           <description>
  155.             http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/jmx/export/naming/MetadataNamingStrategy.html
  156.           </description>
  157.           <property name="attributeSource" ref="jmxAttributeSource" />
  158.           <property name="defaultDomain" value="${jmx.domain}" />
  159.         </bean>
  160.       </property>
  161.       <property name="autodetect" value="true" />
  162.       <property name="autodetectModeName" value="AUTODETECT_ASSEMBLER" />
  163.       <property name="excludedBeans">
  164.         <list>
  165.           <value>dataSource</value>
  166.         </list>
  167.       </property>
  168.       <property name="server" ref="mbeanServer" />
  169.     </bean>
  170.   </beans>
  171.  
  172. </beans>

mybatis.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3.    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4.    "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6.  
  7.   <!--
  8.  Some top level elements of configuration will be IGNORED
  9.  when configured via org.mybatis.spring.SqlSessionFactoryBean.setConfigLocation
  10.  method.
  11.  
  12.  Explicitly documented element is 'environments' (which includes 'dataSource'
  13.  and 'transactionManager' elements).
  14.  Other elements that seem to be IGNORED include 'databaseIdProvider'.
  15.  
  16.  But 'settings', 'typeAliases' and 'mappers' are documented NOT to be ignored.
  17.  
  18.  For more, refer http://mybatis.github.io/spring/factorybean.html#Properties
  19.  -->
  20.  
  21.  
  22.   <!-- http://mybatis.github.io/mybatis-3/configuration.html#settings -->
  23.   <settings>
  24.     <setting name="cacheEnabled" value="true" /> <!-- default : true -->
  25.     <setting name="useColumnLabel" value="true" /> <!-- default : true -->
  26.     <setting name="useGeneratedKeys" value="true" /> <!-- default : false -->
  27.     <setting name="autoMappingUnknownColumnBehavior" value="FAILING"/> <!-- needs MyBatis 3.4.0 or higher -->
  28.     <setting name="defaultExecutorType" value="SIMPLE" /> <!-- SIMPLE(default), REUSE or BATCH -->
  29.     <setting name="mapUnderscoreToCamelCase" value="true" /> <!-- default : false -->
  30.     <setting name="logImpl" value="SLF4J" />
  31.   </settings>
  32.  
  33.   <typeHandlers>
  34.     <typeHandler handler="com.skcc.nexcore.vas.support.mybatis.BooleanYnHandler"
  35.      javaType="boolean" jdbcType="CHAR"/>
  36.   </typeHandlers>
  37. </configuration>

config.properties

  1. jmx.domain = myapp
  2. datasource.jdbcDriver = com.microsoft.sqlserver.jdbc.SQLServerDriver
  3. datasource.jdbcUrl = jdbc:...
  4. datasource.user = SECU
  5. datasource.password = nexcore
  6. datasource.maxTotal = 5
  7. datasource.maxIdle = 5
  8. datasource.minIdle = 0
  9. datasource.initSize = 2
  10. mybatis.configLocation = classpath:.../mybatis.xml
  11. mybatis.mappers.basePackage = myapp.persistence

Check properties of an object using Spring EL

Spring 3.0 introduced powerful expression language (SpEL). We can make a simple utility method to check the properties of an object in any type using SpEL

The following is simple sample.

  1. import org.springframework.expression.ExpressionParser;
  2. import org.springframework.expression.spel.standard.SpelExpressionParser;
  3. import org.springframework.expression.spel.support.StandardEvaluationContext;
  4.  
  5. public class ObjectInspector {
  6.  
  7.    // SpelExpressionParser is thread-safe which is explicitly documented in API doc.
  8.    private ExpressionParser expressionParser = new SpelExpressionParser();
  9.  
  10.    /**
  11.     * Evaluate the given boolean expression against the specified object.
  12.     *
  13.     * This method is thread-safe.
  14.     *
  15.     * @param obj object to check
  16.     * @param booleanExpr boolean expression to evaluate which should be valid with SpEL
  17.     * @param clazz the type of the <code>obj</code>
  18.     */
  19.    public <T> boolean checkBooleanExpression(T obj, String booleanExpr, Class<T> clazz){
  20.  
  21.       StandardEvaluationContext cntx = new StandardEvaluationContext(obj);
  22.       return this.expressionParser.parseExpression(booleanExpr).getValue(cntx, Boolean.class);
  23.    }
  24. }

Note that the method consists of only two line. With the following unit test sample, you can imagine the robustness of the above method.

  1. public class ObjectInspectorTest {
  2.  
  3.    private static ObjectInspector inspector;
  4.  
  5.    @BeforeClass
  6.    public static void setUpBeforeClass() throws Exception {
  7.       inspector = new ObjectInspector();
  8.    }
  9.  
  10.    @Test
  11.    public void testCheckBooleanExpression(){
  12.  
  13.       Person p1 = new Person("Peter", Person.Gender.MALE, (new GregorianCalendar(71, 10, 23)).getTime());
  14.       Person p2 = new Person("Jane", Person.Gender.FEMALE, (new GregorianCalendar(74, 5, 9)).getTime());
  15.  
  16.       //first eye-checking
  17.       System.out.println(p1.toString());
  18.       System.out.println(p2.toString());
  19.  
  20.       Assert.assertTrue(inspector.checkBooleanExpression(p1, "'Peter'.equals(#root.name)", Person.class));
  21.       Assert.assertTrue(inspector.checkBooleanExpression(p2, "#root.birthday.month == 5", Person.class));
  22.  
  23.       Rectangle rct1 = new Rectangle(5, 10, 3, 6);
  24.  
  25.       Assert.assertTrue(inspector.checkBooleanExpression(rct1, "#root.width == 5", Rectangle.class));
  26.       Assert.assertFalse(inspector.checkBooleanExpression(rct1, "#root.height == 5", Rectangle.class));
  27.       Assert.assertTrue(inspector.checkBooleanExpression(rct1, "#root.area == 15", Rectangle.class));
  28.    }
  29. }
  30.  
  31. class Person{
  32.  
  33.    enum Gender{ MALE, FEMALE }
  34.  
  35.    private String name;
  36.    private Gender gender;
  37.    private Date birthday;
  38.  
  39.    public Person(String name, Gender gender, Date date){
  40.       this.name = name;
  41.       this.gender = gender;
  42.       this.birthday = date;
  43.    }
  44.  
  45.    public String getName() { return name; }
  46.    public Gender getGender() { return gender; }
  47.    public Date getBirthday() { return birthday; }
  48.  
  49.    @Override
  50.    public String toString(){
  51.       return String.format("Name : %1$s, Gender : %2$s, Birthday : %3$tF", this.name, this.gender, this.birthday);
  52.    }
  53. }
  54.  
  55.  
  56. class Rectangle{
  57.  
  58.    private int x1;
  59.    private int x2;
  60.    private int y1;
  61.    private int y2;
  62.  
  63.    public Rectangle(int x1, int x2, int y1, int y2){
  64.       if(x1 > x2) throw new IllegalArgumentException("x1 should not greater than x2");
  65.       if(y1 > y2) throw new IllegalArgumentException("y1 should not greater than y2");
  66.  
  67.       this.x1 = x1;
  68.       this.x2 = x2;
  69.       this.y1 = y1;
  70.       this.y2 = y2;
  71.    }
  72.  
  73.    public int getX1() { return x1; }
  74.    public int getX2() { return x2; }
  75.    public int getY1() { return y1; }
  76.    public int getY2() { return y2; }
  77.  
  78.    public int getWidth(){ return (x2 - x1); }
  79.    public int getHeight(){ return (y2 - y1); }
  80.    public int getArea(){ return (this.getWidth())*(this.getHeight()); }
  81. }


Mixing Spring property placeholder configurer and SpEL

  • Properties file : props-server.properties
  1. server.threadpool.mbeanName="bean:name=threadPool2"
  2. server.threadpool.corePoolSize=T(Math).min(T(Runtime).getRuntime().availableProcessors(), 6)
  3. server.threadpool.maxPoolSize=10
  4. server.threadpool.queueCapacity=25
  5. server.threadpool.keepAliveSeconds=10
  6. server.threadpool.threadNamePrefix="toolServerThread-"


  • Spring configuration file : spring-context.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:util="http://www.springframework.org/schema/util"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7.  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
  8.  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  9.  
  10.  <context:property-placeholder location="classpath:sample/server/case2/props-server.properties"/>
  11.  
  12.  <bean id="jmxExporter"
  13.  class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
  14.   <property name="beans">
  15.    <map>
  16.     <entry key="#{${server.threadpool.mbeanName}}" value-ref="threadPool"/>
  17.    </map>
  18.   </property>
  19.  </bean>
  20.  
  21.  <bean id="threadPool"
  22.  class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"
  23.  lazy-init="false">
  24.   <property name="corePoolSize" value="#{${server.threadpool.corePoolSize}}"/>
  25.   <property name="maxPoolSize" value="#{${server.threadpool.maxPoolSize}}"/>
  26.   <property name="threadNamePrefix" value="#{${server.threadpool.threadNamePrefix}}"/>
  27.  </bean>
  28. </beans>

MyBatis

Changing EntityResolver for mapper XML

  1. Create custom DTD extending http://mybatis.org/dtd/mybatis-3-mapper.dtd and locate it in a JAR file
  2. Create custom EntityResolver extending org.apache.ibatis.builder.xml.XMLMapperEntityResolver
  3. Create custom XMLConfigureBuilder extending org.apache.ibatis.builder.xml.XMLConfigBuilder and custom XMLMapperBuilder extending org.apache.ibatis.builder.xml.XMLMapperBuilder
  4. Create custom SqlSessionFactoryBuilder extending org.apache.ibatis.session.SqlSessionFactoryBuilder
  5. Create custom SqlSessionFactoryBean extending org.mybatis.spring.SqlSessionFactoryBean
  • Consideration
    • org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
    • org.apache.ibatis.builder.annotation.MapperAnnotationBuilder
    • org.apache.ibatis.scripting.defaults.RawLanguageDriver

Using OGNL expressions within SQL statement of MyBatis

You can use OGNL expressions with MyBatis using bind element.
For more, refer http://www.mybatis.org/mybatis-3/dynamic-sql.html#bind

   <insert id="insertVisitor" parameterType="face.domain.Visitor"
      useGeneratedKeys="true" keyProperty="visitor.id" keyColumn="id">
      <bind name="isValid" value="(visitor.isValid())? 'Y' : 'N'"/>insert vas_visitor (
 name, is_valid, valid_from, valid_to, pass_no,
 company, tel_no, prsnnl_id, remarks,
 last_update_by, last_update_at
)values(
 #{visitor.name}, #{isValid}, #{visitor.validFrom}, #{visitor.validTo}, #{visitor.passNo},
 #{visitor.company}, #{visitor.telephone}, #{visitor.personnelId}, #{visitor.remarks},
 'appl', replace(replace(replace(convert(varchar(19),getdate(),120),'-',''),':',''),' ','')
);
   </insert>

Custom MyBatis type handler sample

Most of databases don't support intrinsic boolean datatype. JDBC supports implicit and automatic conversion between true/false and '1'/'0' or 1/0.

But '1'/'0' is not so intuitive and other value pairs such as 'Y'/'N', 'y'/'n', 'YES'/'NO', 'T'/'F', or 'true'/'false' would be preferred. Even the combination of those pairs could be wanted for liberated people. The following type handler can be used for this purpose.

  1. /**
  2.  * Maps automatically {@code boolean} type property in Java object and string type column in database.
  3.  * <p>
  4.  * The column handled by this class is expected to be {@code CHAR} or {@code VACHAR} datatype.
  5.  * <p>
  6.  * The mapping for {@code NULL} value in database can be configured in constructor.
  7.  *
  8.  * @see <code>https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/type/BooleanTypeHandler.java</code>
  9.  */
  10. public abstract class BooleanStringHandler extends BaseTypeHandler<Boolean>{
  11.  
  12.    private final org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
  13.  
  14.    /**
  15.     * the list strings that represent {@code true}
  16.     */
  17.    private final List<String> trueValues = new ArrayList<String>();
  18.  
  19.    /**
  20.     * the list strings that represent {@code false}
  21.     */
  22.    private final List<String> falseValues = new ArrayList<String>();
  23.  
  24.    /**
  25.     * determines whether {@code NULL} value in database will be mapped to {@code false} or not.
  26.     */
  27.    private final boolean isNullFalse;
  28.  
  29.    /**
  30.     * At least one string value should be given for each list of {@code true} values and
  31.     * list of {@code false} values.
  32.     * <p>
  33.     * If more than two values are specified, the first value in either list will be used
  34.     * when inserting or updating the database column.
  35.     *
  36.     * @param trueValues
  37.     * @param falseValues
  38.     */
  39.    public BooleanStringHandler(@NotEmpty String[] trueValues, @NotEmpty String[] falseValues, boolean isNullFalse){
  40.       Validate.isTrue(!ArrayUtils.isEmpty(trueValues),
  41.          "At least one string for true should included.");
  42.       Validate.isTrue(!ArrayUtils.isEmpty(falseValues),
  43.          "At least one string for false should included.");
  44.  
  45.       for(int i = 0, n = trueValues.length; i < n; i++){ this.trueValues.add(trueValues[i]); }
  46.       for(int i = 0, n = falseValues.length; i < n; i++){ this.falseValues.add(falseValues[i]); }
  47.       this.isNullFalse = isNullFalse;
  48.    }
  49.  
  50.    @Override
  51.    public void setNonNullParameter(PreparedStatement ps, int i,
  52.       Boolean parameter, JdbcType jdbcType) throws SQLException{
  53.  
  54.       if(parameter){ ps.setString(i, this.trueValues.get(0)); }
  55.       else{ ps.setString(i, this.falseValues.get(0)); }
  56.    }
  57.  
  58.    @Override
  59.    public Boolean getNullableResult(ResultSet rs, String columnName)
  60.       throws SQLException{
  61.  
  62.       String value = rs.getString(columnName);
  63.       if(value == null){ return !isNullFalse; }
  64.       else{ return this.getBooleanFromStringValue(value); }
  65.    }
  66.  
  67.    @Override
  68.    public Boolean getNullableResult(ResultSet rs, int columnIndex)
  69.       throws SQLException{
  70.  
  71.       String value = rs.getString(columnIndex);
  72.       if(value == null){ return !isNullFalse; }
  73.       else{ return this.getBooleanFromStringValue(value); }
  74.    }
  75.  
  76.    @Override
  77.    public Boolean getNullableResult(CallableStatement cs, int columnIndex)
  78.       throws SQLException{
  79.  
  80.       String value = cs.getString(columnIndex);
  81.       if(value == null){ return !isNullFalse; }
  82.       else{ return this.getBooleanFromStringValue(value); }
  83.    }
  84.  
  85.    @Nonnull
  86.    private Boolean getBooleanFromStringValue(String value){
  87.       if(this.trueValues.contains(value)){ return Boolean.TRUE; }
  88.       else if(this.falseValues.contains(value)){ return Boolean.FALSE; }
  89.       else{
  90.          this.logger.error("The value('{}') in database is not among expected values.", value);
  91.          throw new IllegalStateException("The value in database is not among expected values.");
  92.       }
  93.    }
  94. }

The conversion which permits only 'Y'/'N' pair (simplest except '1'/'0') can be handled by the following one. Note that relational database world prefers short(but intuitive enough) and capitalized value for enumerations

/**
 * Maps automatically {@code boolean} type property in Java object and 'Y' or 'N' value in database column.
 * <p>
 * 'Y' or 'N' value in database will be converted to {@code true} or {@code false} value in Java
 * object and vice versa.
 * <p>
 * {@code NULL} value in database will be converted to {@code false}.
 *
 */
public final class BooleanYnHandler extends BooleanStringHandler{
 
   public BooleanYnHandler(){
      super(new String[]{"Y"}, new String[]{"N"}, true);
 
   }
}

To use the above handler, it should be registered MyBatis configuration file

  <typeHandlers>
    <typeHandler handler="support.mybatis.BooleanYnHandler" javaType="boolean" jdbcType="CHAR"/>
  </typeHandlers>

When the Member class has boolean isActive filed and the corresponding column is CHAR(1) TB_MEMBER.IS_ACTIVE in database. MyBatis SQL mapper would like the following.

<insert id="insertMember" resultType="Member">
insert tb_member (id, name, is_active, registered_at)
values (#{member.id}, #{member.isActive,javaType=boolean,jdbcType=CHAR}, #{member.registeredAt})</insert>
 
<select id="selectMemberById">
select id, name, is_active as isActive, registered_at as registerAtfrom tb_member
where id = #{id}
</select>

ActiveMQ

Loading embedded ActiveMQ broker and web console respectively

Maven depedency configuration

Broker

Web console

Jetty

Loading embedded Jetty 9 with JSP and JSTL support

The dependent libraries to enable JSP and JSTL support for Jetty are much various according to the versions or modes of Jetty. There are org.eclipse.jetty:apache-jsp, org.eclipse.jetty:apache-jstl, org.apache.taglibs:taglibs-standard-spec, org.apache.taglibs:taglibs-standard-impl or much more modules.

But these make there can be too many possible configurations and make it difficult to setup correct configuration.

As of Jetty 9, the most simple configuration is using only org.eclipse.jetty:jetty-jsp with no other JSP/JSTL related modules.

  1.       ...
  2.       <dependency>
  3.          <groupId>org.eclipse.jetty</groupId>
  4.          <artifactId>jetty-server</artifactId>
  5.          <version>${jetty.version}</version>
  6.       </dependency>      
  7.       <dependency>
  8.          <groupId>org.eclipse.jetty</groupId>
  9.          <artifactId>jetty-webapp</artifactId>
  10.          <version>${jetty.version}</version>
  11.       </dependency>
  12.       <dependency>
  13.          <groupId>org.eclipse.jetty</groupId>
  14.          <artifactId>jetty-jsp</artifactId>
  15.          <version>${jetty.version}</version>
  16.       </dependency>
  17.       <dependency>
  18.          <groupId>org.eclipse.jetty</groupId>
  19.          <artifactId>jetty-annotations</artifactId>
  20.          <version>${jetty.version}</version>
  21.       </dependency>
  22.       <dependency>
  23.          <groupId>org.eclipse.jetty</groupId>
  24.          <artifactId>jetty-jmx</artifactId>
  25.          <version>${jetty.version}</version>
  26.       </dependency>
  27.       <dependency>
  28.          <groupId>org.eclipse.jetty</groupId>
  29.          <artifactId>jetty-deploy</artifactId>
  30.          <version>${jetty.version}</version>
  31.       </dependency>
  32.       ...

The Java code to setup and load Jetty without jetty.xml is like the following.

  1.       ...
  2.    //final InetAddress addr = InetAddress.getLocalHost();
  3.    final InetAddress addr = InetAddress.getLoopbackAddress();
  4.    final int port = 8080;
  5.    final Server jetty = new Server(new InetSocketAddress(addr, port));
  6.    jetty.addBean(new MBeanContainer(ManagementFactory.getPlatformMBeanServer()));
  7.    Configuration.ClassList.serverDefault(jetty).addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration"
  8.          , "org.eclipse.jetty.annotations.AnnotationConfiguration");
  9.    final String webAppPath = System.getenv("TEMP") + "/activemq-web-console.war";
  10.    final WebAppContext webApp = new WebAppContext(webAppPath, "/admin");
  11.    webApp.setExtractWAR(true);
  12.    webApp.setLogUrlOnStart(true);
  13.    webApp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
  14.          ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$" );
  15.    jetty.setHandler(webApp);
  16.    jetty.setStopAtShutdown(true);
  17.    jetty.start();
  18.    //jetty.join();
  19.    ...

Maven

Simple POM

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  2.    <modelVersion>4.0.0</modelVersion>
  3.    <groupId>thirdstage.exercise</groupId>
  4.    <artifactId>solidity</artifactId>
  5.    <version>0.0.1-SNAPSHOT</version>
  6.  
  7.    <prerequisites>
  8.       <maven>3.0</maven>
  9.    </prerequisites>
  10.  
  11.    <properties>
  12.       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13.       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  14.       <skipTests>false</skipTests>
  15.       <maven.deploy.skip>true</maven.deploy.skip>
  16.       <maven.javadoc.skip>false</maven.javadoc.skip>
  17.       <maven.site.deploy.skip>true</maven.site.deploy.skip>
  18.       <findbugs.skip>true</findbugs.skip>
  19.       <checkstyle.skip>true</checkstyle.skip>
  20.       <java.version>1.7</java.version>
  21.       <slf4j.version>1.7.21</slf4j.version>
  22.       <logback.version>1.1.7</logback.version>
  23.       <junit.version>4.8.2</junit.version>
  24.       <testng.version>6.9.10</testng.version>
  25.       <commons.lang3.version>3.4</commons.lang3.version>
  26.       <spring.version>4.0.9.RELEASE</spring.version>
  27.       <mybatis.version>3.4.0</mybatis.version>
  28.       <jackson.version>2.7.4</jackson.version>
  29.    </properties>
  30.  
  31.    <repositories>
  32.       <repository>
  33.          <snapshots>
  34.             <enabled>false</enabled>
  35.          </snapshots>
  36.          <id>central2</id>
  37.          <url>http://repo2.maven.org/maven2/</url>
  38.       </repository>
  39.       <repository>
  40.          <snapshots>
  41.             <enabled>true</enabled>
  42.          </snapshots>
  43.          <id>java.net.public</id>
  44.          <url>https://maven.java.net/content/groups/public/</url>
  45.       </repository>
  46.    </repositories>
  47.  
  48.    <pluginRepositories>
  49.       <pluginRepository>
  50.          <snapshots>
  51.             <enabled>false</enabled>
  52.          </snapshots>
  53.          <id>central2</id>
  54.          <url>http://repo2.maven.org/maven2/</url>
  55.       </pluginRepository>
  56.    </pluginRepositories>
  57.  
  58.    <reporting>
  59.       <plugins>
  60.       </plugins>
  61.    </reporting>
  62.  
  63.    <build>
  64.       <plugins>
  65.          <plugin>
  66.             <groupId>org.basepom.maven</groupId>
  67.             <artifactId>duplicate-finder-maven-plugin</artifactId>
  68.             <executions>
  69.                <execution>
  70.                   <id>find-duplicate-classes</id>
  71.                   <phase>prepare-package</phase>
  72.                   <goals>
  73.                      <goal>check</goal>
  74.                   </goals>
  75.                </execution>
  76.             </executions>
  77.             <configuration>
  78.                <!-- For more, refer https://github.com/basepom/duplicate-finder-maven-plugin/wiki -->
  79.                <skip>false</skip>
  80.                <checkCompileClasspath>false</checkCompileClasspath>
  81.                <checkRuntimeClasspath>true</checkRuntimeClasspath>
  82.                <checkTestClasspath>false</checkTestClasspath>
  83.                <ignoredResourcePatterns>
  84.                   <ignoredResourcePattern>about.html</ignoredResourcePattern>
  85.                </ignoredResourcePatterns>
  86.                <ignoredDependencies>
  87.                   <dependency>
  88.                      <groupId>org.slf4j</groupId>
  89.                      <artifactId>jcl-over-slf4j</artifactId>
  90.                   </dependency>
  91.                </ignoredDependencies>
  92.             </configuration>
  93.          </plugin>
  94.       </plugins>
  95.       <pluginManagement>
  96.          <plugins>
  97.             <!-- core -->
  98.             <plugin>
  99.                <groupId>org.apache.maven.plugins</groupId>
  100.                <artifactId>maven-compiler-plugin</artifactId>
  101.                <version>2.3.2</version>
  102.                <inherited>true</inherited>
  103.                <configuration>
  104.                   <source>${java.version}</source>
  105.                   <target>${java.version}</target>
  106.                </configuration>
  107.             </plugin>
  108.             <plugin>
  109.                <groupId>org.apache.maven.plugins</groupId>
  110.                <artifactId>maven-site-plugin</artifactId>
  111.                <version>3.0</version>
  112.                <dependencies>
  113.                   <dependency>
  114.                      <groupId>org.apache.maven.wagon</groupId>
  115.                      <artifactId>wagon-ssh</artifactId>
  116.                      <version>2.0</version>
  117.                   </dependency>
  118.                </dependencies>
  119.             </plugin>
  120.             <!-- packaging -->
  121.             <plugin>
  122.                <groupId>org.apache.maven.plugins</groupId>
  123.                <artifactId>maven-jar-plugin</artifactId>
  124.                <version>2.3.2</version>
  125.                <configuration>
  126.                   <!-- For more on Maven archiver, refer http://maven.apache.org/shared/maven-archiver/index.html -->
  127.                   <archive>
  128.                      <addMavenDescriptor>false</addMavenDescriptor>
  129.                      <forced>true</forced>
  130.                      <index>true</index>
  131.                      <manifest>
  132.                         <addClasspath>false</addClasspath>
  133.                         <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
  134.                         <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
  135.                         <addExtensions>false</addExtensions>
  136.                         <classpathLayoutType>simple</classpathLayoutType>
  137.                      </manifest>
  138.                      <manifestEntries>
  139.                         <Source-Revision>${project.svn.revision}</Source-Revision>
  140.                      </manifestEntries>
  141.                   </archive>
  142.                </configuration>
  143.             </plugin>
  144.             <!-- reporting -->
  145.             <plugin>
  146.                <groupId>org.apache.maven.plugins</groupId>
  147.                <artifactId>maven-javadoc-plugin</artifactId>
  148.                <version>2.8</version>
  149.                <configuration>
  150.                   <additionalJOptions>
  151.                      <additionalJOption>-Xms128m</additionalJOption>
  152.                   </additionalJOptions>
  153.                   <docencoding>${project.reporting.outputEncoding}</docencoding>
  154.                   <encoding>${project.build.sourceEncoding}</encoding>
  155.                   <doctitle>${project.name} ${project.version} API</doctitle>
  156.                   <windowtitle>${project.name} ${project.version} API</windowtitle>
  157.                   <links>
  158.                      <link>http://docs.oracle.com/javase/7/docs/api/</link>
  159.                      <link>http://docs.oracle.com/javaee/6/api/</link>
  160.                      <link>http://jsr-305.googlecode.com/svn/trunk/javadoc/</link>
  161.                      <link>http://docs.jboss.org/hibernate/beanvalidation/spec/1.1/api/</link>
  162.                      <link>http://docs.jboss.org/hibernate/validator/5.2/api/</link>
  163.                      <link>http://commons.apache.org/proper/commons-lang/javadocs/api-3.3.2/</link>
  164.                      <link>http://commons.apache.org/proper/commons-collections/javadocs/api-release/</link>
  165.                      <link>http://docs.spring.io/spring/docs/4.0.x/javadoc-api/</link>
  166.                   </links>
  167.                   <show>projected</show>
  168.                   <splitindex>true</splitindex>
  169.                </configuration>
  170.             </plugin>
  171.             <plugin>
  172.                <groupId>org.apache.maven.plugins</groupId>
  173.                <artifactId>maven-checkstyle-plugin</artifactId>
  174.                <version>2.7</version>
  175.             </plugin>
  176.             <plugin>
  177.                <groupId>org.basepom.maven</groupId>
  178.                <artifactId>duplicate-finder-maven-plugin</artifactId>
  179.                <version>1.2.1</version>
  180.             </plugin>
  181.             <!-- tools supporting -->
  182.             <plugin>
  183.                <!-- http://maven.apache.org/plugins/maven-eclipse-plugin/eclipse-mojo.html -->
  184.                <groupId>org.apache.maven.plugins</groupId>
  185.                <artifactId>maven-eclipse-plugin</artifactId>
  186.                <version>2.9</version>
  187.                <configuration>
  188.                   <!-- the next two item doesn't work on m2e. m2e has its own confgiruation in Eclipse preferences -->
  189.                   <downloadJavadocs>true</downloadJavadocs>
  190.                   <downloadSources>true</downloadSources>
  191.                   <forceRecheck>false</forceRecheck>
  192.                </configuration>
  193.             </plugin>
  194.             <plugin>
  195.                <groupId>org.eclipse.m2e</groupId>
  196.                <artifactId>lifecycle-mapping</artifactId>
  197.                <version>1.0.0</version>
  198.                <configuration>
  199.                   <lifecycleMappingMetadata>
  200.                      <pluginExecutions>
  201.                         <pluginExecution>
  202.                            <pluginExecutionFilter>
  203.                               <groupId>org.apache.maven.plugins</groupId>
  204.                               <artifactId>maven-dependency-plugin</artifactId>
  205.                               <versionRange>[1.0.0,)</versionRange>
  206.                               <goals>
  207.                                  <goal>copy-dependencies</goal>
  208.                               </goals>
  209.                            </pluginExecutionFilter>
  210.                            <action>
  211.                               <ignore />
  212.                            </action>
  213.                         </pluginExecution>
  214.                         <pluginExecution>
  215.                            <pluginExecutionFilter>
  216.                               <groupId>org.apache.maven.plugins</groupId>
  217.                               <artifactId>maven-antrun-plugin</artifactId>
  218.                               <versionRange>[1.0.0,)</versionRange>
  219.                               <goals>
  220.                                  <goal>run</goal>
  221.                               </goals>
  222.                            </pluginExecutionFilter>
  223.                            <action>
  224.                               <ignore />
  225.                            </action>
  226.                         </pluginExecution>
  227.                         <pluginExecution>
  228.                            <pluginExecutionFilter>
  229.                               <groupId>org.codehaus.mojo</groupId>
  230.                               <artifactId>aspectj-maven-plugin</artifactId>
  231.                               <versionRange>[1.0.0,)</versionRange>
  232.                               <goals>
  233.                                  <goal>compile</goal>
  234.                                  <goal>test-compile</goal>
  235.                               </goals>
  236.                            </pluginExecutionFilter>
  237.                            <action>
  238.                               <ignore />
  239.                            </action>
  240.                         </pluginExecution>
  241.                         <pluginExecution>
  242.                            <pluginExecutionFilter>
  243.                               <groupId>org.codehaus.mojo</groupId>
  244.                               <artifactId>build-helper-maven-plugin</artifactId>
  245.                               <versionRange>[1.0.0,)</versionRange>
  246.                               <goals>
  247.                                  <goal>parse-version</goal>
  248.                               </goals>
  249.                            </pluginExecutionFilter>
  250.                            <action>
  251.                               <ignore />
  252.                            </action>
  253.                         </pluginExecution>
  254.                         <pluginExecution>
  255.                            <pluginExecutionFilter>
  256.                               <groupId>net.alchim31.maven</groupId>
  257.                               <artifactId>scala-maven-plugin</artifactId>
  258.                               <versionRange>[1.0.0,)</versionRange>
  259.                               <goals>
  260.                                  <goal>add-source</goal>
  261.                                  <goal>compile</goal>
  262.                                  <goal>testCompile</goal>
  263.                               </goals>
  264.                            </pluginExecutionFilter>
  265.                            <action>
  266.                               <ignore />
  267.                            </action>
  268.                         </pluginExecution>
  269.                      </pluginExecutions>
  270.                   </lifecycleMappingMetadata>
  271.                </configuration>
  272.             </plugin>
  273.          </plugins>
  274.       </pluginManagement>
  275.    </build>
  276.  
  277.    <dependencies>
  278.       <dependency>
  279.          <groupId>com.google.code.findbugs</groupId>
  280.          <artifactId>jsr305</artifactId>
  281.       </dependency>
  282.       <dependency>
  283.          <groupId>javax.inject</groupId>
  284.          <artifactId>javax.inject</artifactId>
  285.       </dependency>
  286.       <dependency>
  287.          <groupId>javax.validation</groupId>
  288.          <artifactId>validation-api</artifactId>
  289.       </dependency>
  290.       <dependency>
  291.          <groupId>org.hibernate</groupId>
  292.          <artifactId>hibernate-validator</artifactId>
  293.       </dependency>
  294.       <dependency>
  295.          <groupId>org.slf4j</groupId>
  296.          <artifactId>slf4j-api</artifactId>
  297.       </dependency>
  298.       <dependency>
  299.          <groupId>org.slf4j</groupId>
  300.          <artifactId>jcl-over-slf4j</artifactId>
  301.       </dependency>
  302.       <dependency>
  303.          <groupId>ch.qos.logback</groupId>
  304.          <artifactId>logback-classic</artifactId>
  305.       </dependency>
  306.       <dependency>
  307.          <groupId>junit</groupId>
  308.          <artifactId>junit</artifactId>
  309.       </dependency>
  310.       <dependency>
  311.          <groupId>org.testng</groupId>
  312.          <artifactId>testng</artifactId>
  313.       </dependency>
  314.       <dependency>
  315.          <groupId>org.apache.commons</groupId>
  316.          <artifactId>commons-lang3</artifactId>
  317.       </dependency>
  318.    </dependencies>
  319.    <dependencyManagement>
  320.       <dependencies>
  321.          <dependency>
  322.             <!-- JSR 305 annotations which includes also JCIP annotations -->
  323.             <groupId>com.google.code.findbugs</groupId>
  324.             <artifactId>jsr305</artifactId>
  325.             <version>2.0.3</version>
  326.          </dependency>
  327.          <dependency>
  328.             <!-- JSR 330 annotations -->
  329.             <groupId>javax.inject</groupId>
  330.             <artifactId>javax.inject</artifactId>
  331.             <version>1</version>
  332.          </dependency>
  333.          <dependency>
  334.             <!-- JSR 349 annotations -->
  335.             <groupId>javax.validation</groupId>
  336.             <artifactId>validation-api</artifactId>
  337.             <version>1.1.0.Final</version>
  338.          </dependency>
  339.          <dependency>
  340.             <!-- Hibernate Validator -->
  341.             <groupId>org.hibernate</groupId>
  342.             <artifactId>hibernate-validator</artifactId>
  343.             <version>5.2.4.Final</version>
  344.          </dependency>
  345.          <dependency>
  346.             <groupId>org.slf4j</groupId>
  347.             <artifactId>slf4j-api</artifactId>
  348.             <version>${slf4j.version}</version>
  349.          </dependency>
  350.          <dependency>
  351.             <groupId>org.slf4j</groupId>
  352.             <artifactId>jcl-over-slf4j</artifactId>
  353.             <version>${slf4j.version}</version>
  354.          </dependency>
  355.          <dependency>
  356.             <groupId>ch.qos.logback</groupId>
  357.             <artifactId>logback-classic</artifactId>
  358.             <version>${logback.version}</version>
  359.          </dependency>
  360.          <dependency>
  361.             <groupId>org.codehaus.janino</groupId>
  362.             <artifactId>janino</artifactId>
  363.             <version>2.7.8</version>
  364.          </dependency>
  365.          <dependency>
  366.             <groupId>junit</groupId>
  367.             <artifactId>junit</artifactId>
  368.             <version>${junit.version}</version>
  369.             <scope>test</scope>
  370.          </dependency>
  371.          <dependency>
  372.             <groupId>org.testng</groupId>
  373.             <artifactId>testng</artifactId>
  374.             <version>${testng.version}</version>
  375.             <scope>test</scope>
  376.          </dependency>
  377.          <dependency>
  378.             <groupId>org.mockito</groupId>
  379.             <artifactId>mockito-core</artifactId>
  380.             <version>${mockito.version}</version>
  381.             <scope>test</scope>
  382.          </dependency>
  383.          <dependency>
  384.             <groupId>org.apache.commons</groupId>
  385.             <artifactId>commons-lang3</artifactId>
  386.             <version>${commons.lang3.version}</version>
  387.          </dependency>
  388.       </dependencies>
  389.    </dependencyManagement>
  390. </project>

Typical sample of parent POM

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.  
  4.   <!-- For more on Maven project descriptor, refer http://maven.apache.org/ref/2.2.1/maven-model/maven.html -->
  5.   <modelVersion>4.0.0</modelVersion>
  6.   <groupId>thridstage</groupId>
  7.   <artifactId>thridstage-framework-parent</artifactId>
  8.   <version>3.0.0-SNAPSHOT</version>
  9.   <packaging>pom</packaging>
  10.  
  11.   <name>Thirdstage Framework</name>
  12.   <url>...</url>
  13.   <inceptionYear>2012</inceptionYear>
  14.   <organization>
  15.     <name>...</name>
  16.     <url>...</url>
  17.   </organization>
  18.  
  19.   <prerequisites>
  20.     <maven>3.0</maven>
  21.   </prerequisites>
  22.  
  23.   <properties>
  24.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  25.     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  26.     <graphviz.home>${env.GRAPHVIZ_HOME}</graphviz.home>
  27.     <skipTests>false</skipTests>
  28.     <maven.deploy.skip>true</maven.deploy.skip>
  29.     <maven.javadoc.skip>false</maven.javadoc.skip>
  30.     <maven.site.deploy.skip>true</maven.site.deploy.skip>
  31.     <findbugs.skip>true</findbugs.skip>
  32.     <checkstyle.skip>true</checkstyle.skip>
  33.     <java.version>1.7</java.version>
  34.     <slf4j.version>1.7.21</slf4j.version>
  35.     <logback.version>1.1.7</logback.version>
  36.     <junit.version>4.8.2</junit.version>
  37.     <testng.version>6.9.10</testng.version>
  38.     <commons.lang3.version>3.4</commons.lang3.version>
  39.     <spring.version>4.0.9.RELEASE</spring.version>
  40.     <mybatis.version>3.4.0</mybatis.version>
  41.     <jackson.version>2.7.4</jackson.version>
  42.     <dependency.locations.enabled>false</dependency.locations.enabled>
  43.     <antrun.echos.properties>true</antrun.echos.properties>
  44.     <scm.url.base>...</scm.url.base>
  45.   </properties>
  46.  
  47.   <issueManagement>
  48.     <system>Redmine</system>
  49.     <url>.../issues</url>
  50.   </issueManagement>
  51.   <scm>
  52.     <connection>scm:svn:http:...</connection>
  53.     <url>http:...</url>
  54.   </scm>
  55.   <distributionManagement>
  56.     <repository>
  57.       <id>...</id>
  58.       <name>...</name>
  59.       <url>...</url>
  60.     </repository>
  61.     <snapshotRepository>
  62.       <id>...</id>
  63.       <name>...</name>
  64.       <url>...</url>
  65.     </snapshotRepository>
  66.     <site>
  67.       <id>...</id>
  68.       <url>sftp://.../${project.version}</url>
  69.     </site>
  70.   </distributionManagement>
  71.  
  72.   <repositories>
  73.     <repository>
  74.       <snapshots>
  75.         <enabled>false</enabled>
  76.       </snapshots>
  77.       <id>thirdstag-releases</id>
  78.       <url>...</url>
  79.     </repository>
  80.     <repository>
  81.       <releases>
  82.         <enabled>false</enabled>
  83.       </releases>
  84.       <snapshots>
  85.         <enabled>true</enabled>
  86.       </snapshots>
  87.       <id>thirdstage-snapshots</id>
  88.       <url>...</url>
  89.     </repository>
  90.     <repository>
  91.       <snapshots>
  92.         <enabled>false</enabled>
  93.       </snapshots>
  94.       <id>central2</id>
  95.       <url>http://repo2.maven.org/maven2/</url>
  96.     </repository>
  97.     <repository>
  98.       <snapshots>
  99.         <enabled>false</enabled>
  100.       </snapshots>
  101.       <id>maven2-repository.dev.java.net</id>
  102.       <name>Java.net Repository for Maven</name>
  103.       <url>http://download.java.net/maven/2/</url>
  104.     </repository>
  105.     <repository>
  106.       <snapshots>
  107.         <enabled>false</enabled>
  108.       </snapshots>
  109.       <id>thirdparty</id>
  110.       <name>3rd-party Repository</name>
  111.       <url>http://repo.expertvill.net/nexus/content/repositories/thirdparty</url>
  112.     </repository>
  113.     <repository>
  114.       <id>evolvis-3rdparty</id>
  115.       <url>http://maven-repo.evolvis.org/3rdparty</url>
  116.     </repository>
  117.   </repositories>
  118.   <pluginRepositories>
  119.     <pluginRepository>
  120.       <snapshots>
  121.         <enabled>false</enabled>
  122.       </snapshots>
  123.       <id>central2</id>
  124.       <url>http://repo2.maven.org/maven2/</url>
  125.     </pluginRepository>
  126.     <pluginRepository>
  127.       <snapshots>
  128.         <enabled>false</enabled>
  129.       </snapshots>
  130.       <id>spring-beandoc</id>
  131.       <url>http://spring-beandoc.sourceforge.net/repo</url>
  132.     </pluginRepository>
  133.     <pluginRepository>
  134.       <snapshots>
  135.         <enabled>false</enabled>
  136.       </snapshots>
  137.       <id>tmatesoft-releases</id>
  138.       <url>http://maven.tmatesoft.com/content/repositories/releases/</url>
  139.     </pluginRepository>
  140.     <pluginRepository>
  141.       <releases>
  142.         <enabled>false</enabled>
  143.       </releases>
  144.       <id>tmatesoft-snapshots</id>
  145.       <url>http://maven.tmatesoft.com/content/repositories/snapshots/</url>
  146.     </pluginRepository>
  147.     <pluginRepository>
  148.       <id>evolvis-3rdparty</id>
  149.       <url>http://maven-repo.evolvis.org/3rdparty</url>
  150.     </pluginRepository>
  151.     <pluginRepository>
  152.       <snapshots>
  153.         <enabled>false</enabled>
  154.       </snapshots>
  155.       <id>elca-services</id>
  156.       <url>http://el4.elca-services.ch/el4j/maven2repository</url>
  157.     </pluginRepository>
  158.   </pluginRepositories>
  159.  
  160.   <reporting>
  161.     <plugins>
  162.       <plugin>
  163.         <groupId>org.apache.maven.plugins</groupId>
  164.         <artifactId>maven-checkstyle-plugin</artifactId>
  165.         <configuration>
  166.           <configLocation>../thirdstage.framework.parent/src/main/config/checkstyle/checkstyle.xml</configLocation>
  167.           <propertyExpansion>parent.basedir=../thirdstage.framework.parent</propertyExpansion>
  168.           <failsOnError>false</failsOnError>
  169.         </configuration>
  170.       </plugin>
  171.       <plugin>
  172.         <groupId>org.codehaus.mojo</groupId>
  173.         <artifactId>findbugs-maven-plugin</artifactId>
  174.         <version>2.3.2</version>
  175.         <configuration>
  176.           <effort>Max</effort>
  177.           <threshold>Low</threshold>
  178.           <onlyAnalyze>thirdstage.framework.*</onlyAnalyze>
  179.           <excludeFilterFile>../thirdstage.framework.parent/src/main/config/findbugs/findbugs-exclude.xml</excludeFilterFile>
  180.           <fork>true</fork>
  181.           <timeout>600000</timeout>
  182.           <maxHeap>512</maxHeap>
  183.         </configuration>
  184.       </plugin>
  185.     </plugins>
  186.   </reporting>
  187.  
  188.   <build>
  189.     <plugins>
  190.       <plugin>
  191.         <groupId>org.apache.maven.plugins</groupId>
  192.         <artifactId>maven-enforcer-plugin</artifactId>
  193.         <executions>
  194.           <execution>
  195.             <id>enforce-requirements</id>
  196.             <goals>
  197.               <goal>enforce</goal>
  198.             </goals>
  199.             <configuration>
  200.               <!-- For more standard rules, refer http://maven.apache.org/enforcer/enforcer-rules/ -->
  201.               <rules>
  202.                 <requireJavaVersion>
  203.                   <version>${java.version}</version>
  204.                 </requireJavaVersion>
  205.                 <requireMavenVersion>
  206.                   <version>3.0</version>
  207.                 </requireMavenVersion>
  208.                 <requireEnvironmentVariable>
  209.                   <variableName>OPENCV_DIR</variableName>
  210.                   <variableName>MINGW_HOME</variableName>
  211.                 </requireEnvironmentVariable>
  212.               </rules>
  213.             </configuration>
  214.           </execution>
  215.         </executions>
  216.       </plugin>
  217.       <plugin>
  218.         <groupId>org.apache.maven.plugins</groupId>
  219.         <artifactId>maven-javadoc-plugin</artifactId>
  220.         <executions>
  221.           <execution>
  222.             <id>attach-javadocs</id>
  223.             <goals>
  224.               <goal>jar</goal>
  225.             </goals>
  226.           </execution>
  227.         </executions>
  228.       </plugin>
  229.       <plugin>
  230.         <groupId>org.apache.maven.plugins</groupId>
  231.         <artifactId>maven-jar-plugin</artifactId>
  232.         <executions>
  233.           <execution>
  234.             <goals>
  235.               <goal>test-jar</goal>
  236.             </goals>
  237.           </execution>
  238.         </executions>
  239.       </plugin>
  240.       <plugin>
  241.         <groupId>org.apache.maven.plugins</groupId>
  242.         <artifactId>maven-assembly-plugin</artifactId>
  243.         <!-- Unveil the commented block when jar-with-dependencies is necessary
  244.        <executions>
  245.          <execution>
  246.            <id>jar-with-deps</id>
  247.            <phase>package</phase>
  248.            <goals>
  249.              <goal>single</goal>
  250.            </goals>
  251.            <configuration>
  252.              <descriptorRefs>
  253.                <descriptorRef>jar-with-dependencies</descriptorRef>
  254.              </descriptorRefs>
  255.            </configuration>
  256.          </execution>
  257.        </executions>
  258.        -->
  259.       </plugin>
  260.       <plugin>
  261.         <groupId>org.apache.maven.plugins</groupId>
  262.         <artifactId>maven-antrun-plugin</artifactId>
  263.         <executions>
  264.           <execution>
  265.             <id>validate-properties</id>
  266.             <phase>validate</phase>
  267.             <goals>
  268.               <goal>run</goal>
  269.             </goals>
  270.             <configuration>
  271.               <failOnError>true</failOnError>
  272.               <target name="validate-properties">
  273.                 <taskdef name="if" classname="ise.antelope.tasks.IfTask" classpathref="maven.plugin.classpath" />
  274.  
  275.                 <if name="antrun.echos.properties" value="true">
  276.                   <echo>Head revision of the project "${project.artifactId}" is
  277.                     ${project.svn.revision}.</echo>
  278.                   <echo>project.artifactId : ${project.artifactId}</echo>
  279.                   <echo>project.basedir : ${project.basedir}</echo>
  280.                   <echo>project.resources.0.directory : ${project.resources.0.directory}</echo>
  281.                   <echo>project.resources[0].directory : ${project.resources[0].directory}</echo>
  282.                   <echo>project.parent : ${project.parent}</echo>
  283.                   <echo>project.parent.groupId : ${project.parent.groupId}</echo>
  284.                   <echo>project.parent.artifactId : ${project.parent.artifactId}</echo>
  285.                   <echo>project.parent.relativePath :
  286.                     ${project.parent.relativePath}</echo>
  287.  
  288.                   <pathconvert pathsep="${line.separator}" property="classpath.maven.plugin"
  289.                    refid="maven.plugin.classpath" />
  290.  
  291.                   <pathconvert pathsep="${line.separator}" property="classpath.maven.compile"
  292.                    refid="maven.compile.classpath" />
  293.                   <echo />
  294.                   <echo>Compile-time classpath for Maven :</echo>
  295.                   <echo>${classpath.maven.compile}</echo>
  296.  
  297.                   <pathconvert pathsep="${line.separator}" property="classpath.maven.runtime"
  298.                    refid="maven.runtime.classpath" />
  299.                   <echo />
  300.                   <echo>Run-time classpath for Maven :</echo>
  301.                   <echo>${classpath.maven.runtime}</echo>
  302.  
  303.                   <echo>Check Korean output : 한글이 정상적으로 보이나요?</echo>
  304.  
  305.                   <!-- echo all properties passed to Ant and environment variables prefixed with 'env' -->
  306.                   <echo>All properties given to Ant are : </echo>
  307.                   <property environment="env" />
  308.                   <echoproperties />
  309.                 </if>
  310.               </target>
  311.             </configuration>
  312.           </execution>
  313.         </executions>
  314.         <dependencies>
  315.           <dependency>
  316.             <groupId>ise.antelope</groupId>
  317.             <artifactId>ant-antelope-tasks</artifactId>
  318.             <version>3.5.0</version>
  319.           </dependency>
  320.         </dependencies>
  321.       </plugin>
  322.       <plugin>
  323.         <groupId>org.apache.maven.plugins</groupId>
  324.         <artifactId>maven-release-plugin</artifactId>
  325.         <configuration>
  326.           <!--
  327.          @fixme javaHome doesn't seem to work as is explained.
  328.          You should specify JAVA_HOME env. variable explicitly in your run configuration when running from
  329.          Eclipse.
  330.           -->
  331.           <!--  <javaHome>c:\lang\jdk1.5</javaHome> -->
  332.  
  333.           <!--  <mavenHome>C:\tools\maven-3.0.3</mavenHome> -->
  334.           <tagBase>${scm.url.base}/main/tags</tagBase>
  335.           <tagNameFormat>@{project.version}</tagNameFormat>
  336.           <username>OhSangMoon</username>
  337.           <autoVersionSubmodules>true</autoVersionSubmodules>
  338.           <pomFileName>pom.xml</pomFileName>
  339.           <arguments>-f pom.xml</arguments>
  340.  
  341.           <!--  not supported by release plugin oer 2.2.2
  342.          <generateReleasePoms>true</generateReleasePoms>
  343.          -->
  344.         </configuration>
  345.       </plugin>
  346.       <plugin>
  347.         <groupId>org.apache.maven.plugins</groupId>
  348.         <artifactId>maven-eclipse-plugin</artifactId>
  349.       </plugin>
  350.       <plugin>
  351.         <groupId>org.codehaus.mojo</groupId>
  352.         <artifactId>aspectj-maven-plugin</artifactId>
  353.         <executions>
  354.           <execution>
  355.             <goals>
  356.               <goal>compile</goal>
  357.               <goal>test-compile</goal>
  358.             </goals>
  359.             <configuration>
  360.               <Xlint>warning</Xlint>
  361.             </configuration>
  362.           </execution>
  363.         </executions>
  364.       </plugin>
  365.       <plugin>
  366.         <groupId>org.basepom.maven</groupId>
  367.         <artifactId>duplicate-finder-maven-plugin</artifactId>
  368.         <executions>
  369.           <execution>
  370.             <id>find-duplicate-classes</id>
  371.             <phase>prepare-package</phase>
  372.             <goals><goal>check</goal></goals>
  373.           </execution>
  374.         </executions>
  375.         <configuration>
  376.           <!-- For more, refer https://github.com/basepom/duplicate-finder-maven-plugin/wiki -->
  377.           <skip>false</skip>
  378.           <checkCompileClasspath>false</checkCompileClasspath>
  379.           <checkRuntimeClasspath>true</checkRuntimeClasspath>
  380.           <checkTestClasspath>false</checkTestClasspath>
  381.           <ignoredResourcePatterns>
  382.             <ignoredResourcePattern>about.html</ignoredResourcePattern>
  383.           </ignoredResourcePatterns>
  384.           <ignoredDependencies>
  385.             <dependency>
  386.               <groupId>org.slf4j</groupId>
  387.               <artifactId>jcl-over-slf4j</artifactId>
  388.             </dependency>
  389.           </ignoredDependencies>
  390.         </configuration>
  391.       </plugin>
  392.     </plugins>
  393.     <pluginManagement>
  394.       <plugins>
  395.         <!-- core -->
  396.         <plugin>
  397.           <groupId>org.apache.maven.plugins</groupId>
  398.           <artifactId>maven-compiler-plugin</artifactId>
  399.           <version>2.3.2</version>
  400.           <inherited>true</inherited>
  401.           <configuration>
  402.             <source>${java.version}</source>
  403.             <target>${java.version}</target>
  404.           </configuration>
  405.         </plugin>
  406.         <plugin>
  407.           <groupId>org.apache.maven.plugins</groupId>
  408.           <artifactId>maven-site-plugin</artifactId>
  409.           <version>3.0</version>
  410.           <dependencies>
  411.             <dependency>
  412.               <groupId>org.apache.maven.wagon</groupId>
  413.               <artifactId>wagon-ssh</artifactId>
  414.               <version>2.0</version>
  415.             </dependency>
  416.           </dependencies>
  417.         </plugin>
  418.         <!-- packaging -->
  419.         <plugin>
  420.           <groupId>org.apache.maven.plugins</groupId>
  421.           <artifactId>maven-jar-plugin</artifactId>
  422.           <version>2.3.2</version>
  423.           <configuration>
  424.             <!-- For more on Maven archiver, refer http://maven.apache.org/shared/maven-archiver/index.html -->
  425.             <archive>
  426.               <addMavenDescriptor>false</addMavenDescriptor>
  427.               <forced>true</forced>
  428.               <index>true</index>
  429.               <manifest>
  430.                 <addClasspath>false</addClasspath>
  431.                 <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
  432.                 <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
  433.                 <addExtensions>false</addExtensions>
  434.                 <classpathLayoutType>simple</classpathLayoutType>
  435.               </manifest>
  436.               <manifestEntries>
  437.                 <Source-Revision>${project.svn.revision}</Source-Revision>
  438.               </manifestEntries>
  439.             </archive>
  440.           </configuration>
  441.         </plugin>
  442.  
  443.         <!-- reporting -->
  444.         <plugin>
  445.           <groupId>org.apache.maven.plugins</groupId>
  446.           <artifactId>maven-project-info-reports-plugin</artifactId>
  447.           <version>2.4</version>
  448.         </plugin>
  449.         <plugin>
  450.           <groupId>org.apache.maven.plugins</groupId>
  451.           <artifactId>maven-javadoc-plugin</artifactId>
  452.           <version>2.8</version>
  453.           <configuration>
  454.             <additionalJOptions>
  455.               <additionalJOption>-Xms128m</additionalJOption>
  456.             </additionalJOptions>
  457.             <docencoding>${project.reporting.outputEncoding}</docencoding>
  458.             <encoding>${project.build.sourceEncoding}</encoding>
  459.             <doctitle>${project.name} ${project.version} API</doctitle>
  460.             <windowtitle>${project.name} ${project.version} API</windowtitle>
  461.             <links>
  462.               <link>http://docs.oracle.com/javase/7/docs/api/</link>
  463.               <link>http://docs.oracle.com/javaee/6/api/</link>
  464.               <link>http://jsr-305.googlecode.com/svn/trunk/javadoc/</link>
  465.               <link>http://docs.jboss.org/hibernate/beanvalidation/spec/1.1/api/</link>
  466.               <link>http://docs.jboss.org/hibernate/validator/5.2/api/</link>
  467.               <link>http://commons.apache.org/proper/commons-lang/javadocs/api-3.3.2/</link>
  468.               <link>http://commons.apache.org/proper/commons-collections/javadocs/api-release/</link>
  469.               <link>http://docs.spring.io/spring/docs/4.0.x/javadoc-api/</link>
  470.             </links>
  471.             <show>projected</show>
  472.             <splitindex>true</splitindex>
  473.             <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
  474.             <docletArtifact>
  475.               <groupId>org.umlgraph</groupId>
  476.               <artifactId>umlgraph</artifactId>
  477.               <version>5.6.6</version>
  478.             </docletArtifact>
  479.             <!-- For more on UMLGraph's option, refer http://www.umlgraph.org/doc/indexw.html -->
  480.             <additionalparam>-inferrel</additionalparam>
  481.             <additionalparam>-hide (java|javax).*</additionalparam>
  482.             <additionalparam>-collpackages java.util.*</additionalparam>
  483.             <useStandardDocletOptions>true</useStandardDocletOptions>
  484.           </configuration>
  485.         </plugin>
  486.         <plugin>
  487.           <groupId>org.codehaus.mojo</groupId>
  488.           <artifactId>maven-springbeandoc-plugin</artifactId>
  489.           <version>1.0.8-SNAPSHOT</version>
  490.         </plugin>
  491.         <plugin>
  492.           <groupId>org.apache.maven.plugins</groupId>
  493.           <artifactId>maven-checkstyle-plugin</artifactId>
  494.           <version>2.7</version>
  495.         </plugin>
  496.         <plugin>
  497.           <groupId>org.basepom.maven</groupId>
  498.           <artifactId>duplicate-finder-maven-plugin</artifactId>
  499.           <version>1.2.1</version>
  500.         </plugin>
  501.         <!-- tools supporting -->
  502.         <plugin>
  503.           <groupId>org.apache.maven.plugins</groupId>
  504.           <artifactId>maven-enforcer-plugin</artifactId>
  505.           <version>1.4</version>
  506.         </plugin>
  507.         <plugin>
  508.           <groupId>org.apache.maven.plugins</groupId>
  509.           <artifactId>maven-assembly-plugin</artifactId>
  510.           <version>2.2.1</version>
  511.         </plugin>
  512.         <plugin>
  513.           <groupId>org.apache.maven.plugins</groupId>
  514.           <artifactId>maven-dependency-plugin</artifactId>
  515.           <version>2.4</version>
  516.         </plugin>
  517.         <plugin>
  518.           <groupId>org.apache.maven.plugins</groupId>
  519.           <artifactId>maven-release-plugin</artifactId>
  520.           <version>2.2.2</version>
  521.           <configuration>
  522.             <providerImplementations>
  523.               <svn>javasvn</svn>
  524.             </providerImplementations>
  525.           </configuration>
  526.           <dependencies>
  527.             <dependency>
  528.               <groupId>com.google.code.maven-scm-provider-svnjava</groupId>
  529.               <artifactId>maven-scm-provider-svnjava</artifactId>
  530.               <version>1.15</version>
  531.             </dependency>
  532.             <dependency>
  533.               <groupId>org.tmatesoft.svnkit</groupId>
  534.               <artifactId>svnkit</artifactId>
  535.               <version>1.7.0-SNAPSHOT</version>
  536.             </dependency>
  537.           </dependencies>
  538.         </plugin>
  539.         <plugin>
  540.           <groupId>org.apache.maven.plugins</groupId>
  541.           <artifactId>maven-scm-plugin</artifactId>
  542.           <version>1.6</version>
  543.           <configuration>
  544.             <providerImplementations>
  545.               <svn>javasvn</svn>
  546.             </providerImplementations>
  547.           </configuration>
  548.           <dependencies>
  549.             <dependency>
  550.               <groupId>com.google.code.maven-scm-provider-svnjava</groupId>
  551.               <artifactId>maven-scm-provider-svnjava</artifactId>
  552.               <version>1.15</version>
  553.             </dependency>
  554.             <dependency>
  555.               <groupId>org.tmatesoft.svnkit</groupId>
  556.               <artifactId>svnkit</artifactId>
  557.               <version>1.7.0-SNAPSHOT</version>
  558.             </dependency>
  559.           </dependencies>
  560.         </plugin>
  561.         <plugin>
  562.           <!-- http://maven.apache.org/plugins/maven-eclipse-plugin/eclipse-mojo.html -->
  563.           <groupId>org.apache.maven.plugins</groupId>
  564.           <artifactId>maven-eclipse-plugin</artifactId>
  565.           <version>2.9</version>
  566.           <configuration>
  567.             <!-- the next two item doesn't work on m2e. m2e has its own confgiruation in Eclipse preferences -->
  568.             <downloadJavadocs>true</downloadJavadocs>
  569.             <downloadSources>true</downloadSources>
  570.             <forceRecheck>false</forceRecheck>
  571.           </configuration>
  572.         </plugin>
  573.         <plugin>
  574.           <groupId>org.apache.maven.plugins</groupId>
  575.           <artifactId>maven-antrun-plugin</artifactId>
  576.           <version>1.7</version>
  577.           <dependencies>
  578.             <dependency>
  579.               <groupId>org.apache.ant</groupId>
  580.               <artifactId>ant</artifactId>
  581.               <version>1.8.2</version>
  582.             </dependency>
  583.           </dependencies>
  584.         </plugin>
  585.         <plugin>
  586.           <groupId>org.codehaus.mojo</groupId>
  587.           <artifactId>aspectj-maven-plugin</artifactId>
  588.           <version>1.8</version>
  589.           <configuration>
  590.             <aspectLibraries>
  591.               <aspectLibrary>
  592.                 <groupId>org.springframework</groupId>
  593.                 <artifactId>spring-aspects</artifactId>
  594.               </aspectLibrary>
  595.             </aspectLibraries>
  596.             <source>${java.version}</source>
  597.             <target>${java.version}</target>
  598.             <complianceLevel>${java.version}</complianceLevel>
  599.           </configuration>
  600.         </plugin>
  601.         <plugin>
  602.           <groupId>org.codehaus.mojo</groupId>
  603.           <artifactId>properties-maven-plugin</artifactId>
  604.           <version>1.0-alpha-2</version>
  605.         </plugin>
  606.         <plugin>
  607.           <groupId>com.google.code.maven-svn-revision-number-plugin</groupId>
  608.           <artifactId>maven-svn-revision-number-plugin</artifactId>
  609.           <version>1.7</version>
  610.           <executions>
  611.             <execution>
  612.               <phase>validate</phase>
  613.               <goals>
  614.                 <goal>revision</goal>
  615.               </goals>
  616.               <configuration>
  617.                 <entries>
  618.                   <entry>
  619.                     <path>${project.basedir}</path>
  620.                     <prefix>project.svn</prefix>
  621.                     <depth>infinity</depth>
  622.                     <reportUnversioned>true</reportUnversioned>
  623.                     <reportIgnored>false</reportIgnored>
  624.                     <reportOutOfDate>false</reportOutOfDate>
  625.                   </entry>
  626.                 </entries>
  627.               </configuration>
  628.             </execution>
  629.           </executions>
  630.           <dependencies>
  631.             <dependency>
  632.               <groupId>org.tmatesoft.svnkit</groupId>
  633.               <artifactId>svnkit</artifactId>
  634.               <version>1.7.0-SNAPSHOT</version>
  635.             </dependency>
  636.           </dependencies>
  637.         </plugin>
  638.         <plugin>
  639.           <groupId>org.eclipse.m2e</groupId>
  640.           <artifactId>lifecycle-mapping</artifactId>
  641.           <version>1.0.0</version>
  642.           <configuration>
  643.             <lifecycleMappingMetadata>
  644.               <pluginExecutions>
  645.                 <pluginExecution>
  646.                   <pluginExecutionFilter>
  647.                     <groupId>org.apache.maven.plugins</groupId>
  648.                     <artifactId>maven-dependency-plugin</artifactId>
  649.                     <versionRange>[1.0.0,)</versionRange>
  650.                     <goals>
  651.                       <goal>copy-dependencies</goal>
  652.                     </goals>
  653.                   </pluginExecutionFilter>
  654.                   <action>
  655.                     <ignore />
  656.                   </action>
  657.                 </pluginExecution>
  658.                 <pluginExecution>
  659.                   <pluginExecutionFilter>
  660.                     <groupId>org.apache.maven.plugins</groupId>
  661.                     <artifactId>maven-antrun-plugin</artifactId>
  662.                     <versionRange>[1.0.0,)</versionRange>
  663.                     <goals>
  664.                       <goal>run</goal>
  665.                     </goals>
  666.                   </pluginExecutionFilter>
  667.                   <action>
  668.                     <ignore />
  669.                   </action>
  670.                 </pluginExecution>
  671.                 <pluginExecution>
  672.                   <pluginExecutionFilter>
  673.                     <groupId>org.codehaus.mojo</groupId>
  674.                     <artifactId>aspectj-maven-plugin</artifactId>
  675.                     <versionRange>[1.0.0,)</versionRange>
  676.                     <goals>
  677.                       <goal>compile</goal>
  678.                       <goal>test-compile</goal>
  679.                     </goals>
  680.                   </pluginExecutionFilter>
  681.                   <action>
  682.                     <ignore />
  683.                   </action>
  684.                 </pluginExecution>
  685.                 <pluginExecution>
  686.                   <pluginExecutionFilter>
  687.                     <groupId>org.codehaus.mojo</groupId>
  688.                     <artifactId>build-helper-maven-plugin</artifactId>
  689.                     <versionRange>[1.0.0,)</versionRange>
  690.                     <goals>
  691.                       <goal>parse-version</goal>
  692.                     </goals>
  693.                   </pluginExecutionFilter>
  694.                   <action>
  695.                     <ignore />
  696.                   </action>
  697.                 </pluginExecution>
  698.                 <pluginExecution>
  699.                   <pluginExecutionFilter>
  700.                     <groupId>net.alchim31.maven</groupId>
  701.                     <artifactId>scala-maven-plugin</artifactId>
  702.                     <versionRange>[1.0.0,)</versionRange>
  703.                     <goals>
  704.                       <goal>add-source</goal>
  705.                       <goal>compile</goal>
  706.                       <goal>testCompile</goal>
  707.                     </goals>
  708.                   </pluginExecutionFilter>
  709.                   <action>
  710.                     <ignore/>
  711.                   </action>
  712.                 </pluginExecution>
  713.               </pluginExecutions>
  714.             </lifecycleMappingMetadata>
  715.           </configuration>
  716.         </plugin>
  717.       </plugins>
  718.     </pluginManagement>
  719.   </build>
  720.  
  721.   <dependencies>
  722.     <dependency>
  723.       <groupId>com.google.code.findbugs</groupId>
  724.       <artifactId>jsr305</artifactId>
  725.     </dependency>
  726.     <dependency>
  727.       <groupId>javax.inject</groupId>
  728.       <artifactId>javax.inject</artifactId>
  729.     </dependency>
  730.     <dependency>
  731.       <groupId>javax.validation</groupId>
  732.       <artifactId>validation-api</artifactId>
  733.     </dependency>
  734.     <dependency>
  735.       <groupId>org.hibernate</groupId>
  736.       <artifactId>hibernate-validator</artifactId>
  737.     </dependency>
  738.     <dependency>
  739.       <groupId>org.slf4j</groupId>
  740.       <artifactId>slf4j-api</artifactId>
  741.     </dependency>
  742.     <dependency>
  743.       <groupId>org.slf4j</groupId>
  744.       <artifactId>jcl-over-slf4j</artifactId>
  745.     </dependency>
  746.     <dependency>
  747.       <groupId>ch.qos.logback</groupId>
  748.       <artifactId>logback-classic</artifactId>
  749.     </dependency>
  750.     <dependency>
  751.       <groupId>junit</groupId>
  752.       <artifactId>junit</artifactId>
  753.     </dependency>
  754.     <dependency>
  755.       <groupId>org.testng</groupId>
  756.       <artifactId>testng</artifactId>
  757.     </dependency>
  758.     <dependency>
  759.       <groupId>org.apache.commons</groupId>
  760.       <artifactId>commons-lang3</artifactId>
  761.     </dependency>
  762.   </dependencies>
  763.   <dependencyManagement>
  764.     <dependencies>
  765.       <dependency>
  766.         <!-- JSR 305 annotations which includes also JCIP annotations -->
  767.         <groupId>com.google.code.findbugs</groupId>
  768.         <artifactId>jsr305</artifactId>
  769.         <version>2.0.3</version>
  770.       </dependency>
  771.       <dependency>
  772.         <!-- JSR 330 annotations -->
  773.         <groupId>javax.inject</groupId>
  774.         <artifactId>javax.inject</artifactId>
  775.         <version>1</version>
  776.       </dependency>
  777.       <dependency>
  778.         <!-- JSR 349 annotations -->
  779.         <groupId>javax.validation</groupId>
  780.         <artifactId>validation-api</artifactId>
  781.         <version>1.1.0.Final</version>
  782.       </dependency>
  783.       <dependency>
  784.         <!-- Hibernate Validator -->
  785.         <groupId>org.hibernate</groupId>
  786.         <artifactId>hibernate-validator</artifactId>
  787.         <version>5.2.4.Final</version>
  788.       </dependency>
  789.       <dependency>
  790.         <groupId>org.slf4j</groupId>
  791.         <artifactId>slf4j-api</artifactId>
  792.         <version>${slf4j.version}</version>
  793.       </dependency>
  794.       <dependency>
  795.         <groupId>org.slf4j</groupId>
  796.         <artifactId>jcl-over-slf4j</artifactId>
  797.         <version>${slf4j.version}</version>
  798.       </dependency>
  799.       <dependency>
  800.         <groupId>ch.qos.logback</groupId>
  801.         <artifactId>logback-classic</artifactId>
  802.         <version>${logback.version}</version>
  803.       </dependency>
  804.       <dependency>
  805.         <groupId>org.codehaus.janino</groupId>
  806.         <artifactId>janino</artifactId>
  807.         <version>2.7.8</version>
  808.       </dependency>
  809.       <dependency>
  810.         <groupId>junit</groupId>
  811.         <artifactId>junit</artifactId>
  812.         <version>${junit.version}</version>
  813.         <scope>test</scope>
  814.       </dependency>
  815.       <dependency>
  816.         <groupId>org.testng</groupId>
  817.         <artifactId>testng</artifactId>
  818.         <version>${testng.version}</version>
  819.         <scope>test</scope>
  820.       </dependency>
  821.       <dependency>
  822.         <groupId>org.mockito</groupId>
  823.         <artifactId>mockito-core</artifactId>
  824.         <version>${mockito.version}</version>
  825.         <scope>test</scope>
  826.       </dependency>
  827.       <dependency>
  828.         <groupId>org.apache.commons</groupId>
  829.         <artifactId>commons-lang3</artifactId>
  830.         <version>${commons.lang3.version}</version>
  831.       </dependency>
  832.       <dependency>
  833.         <groupId>commons-io</groupId>
  834.         <artifactId>commons-io</artifactId>
  835.         <version>2.4</version>
  836.       </dependency>
  837.       <dependency>
  838.         <groupId>commons-codec</groupId>
  839.         <artifactId>commons-codec</artifactId>
  840.         <version>1.10</version>
  841.         <scope>test</scope>
  842.       </dependency>
  843.       <dependency>
  844.          <!--For Java 6, Commons DBCP 1.4 MUST be used. -->
  845.         <groupId>commons-dbcp</groupId>
  846.         <artifactId>commons-dbcp</artifactId>
  847.         <version>1.4</version>
  848.       </dependency>
  849.       <dependency>
  850.          <!-- For Java 7, Commons DBCP 2.x MUST be used. -->
  851.          <!-- DBCP 2.x and DBCP 1.4 have difference namespaces. -->
  852.         <groupId>org.apache.commons</groupId>
  853.         <artifactId>commons-dbcp2</artifactId>
  854.         <version>2.1</version>
  855.         <exclusions>
  856.           <exclusion>
  857.             <groupId>commons-logging</groupId>
  858.             <artifactId>commons-logging</artifactId>
  859.           </exclusion>
  860.         </exclusions>
  861.       </dependency>
  862.       <dependency>
  863.         <groupId>org.springframework</groupId>
  864.         <artifactId>spring-core</artifactId>
  865.         <version>${spring.version}</version>
  866.         <exclusions>
  867.           <exclusion>
  868.             <groupId>commons-logging</groupId>
  869.             <artifactId>commons-logging</artifactId>
  870.           </exclusion>
  871.         </exclusions>
  872.       </dependency>
  873.       <dependency>
  874.         <groupId>org.springframework</groupId>
  875.         <artifactId>spring-beans</artifactId>
  876.         <version>${spring.version}</version>
  877.       </dependency>
  878.       <dependency>
  879.         <groupId>org.springframework</groupId>
  880.         <artifactId>spring-context</artifactId>
  881.         <version>${spring.version}</version>
  882.       </dependency>
  883.       <dependency>
  884.         <groupId>org.springframework</groupId>
  885.         <artifactId>spring-expression</artifactId>
  886.         <version>${spring.version}</version>
  887.       </dependency>
  888.       <dependency>
  889.         <groupId>org.springframework</groupId>
  890.         <artifactId>spring-aspects</artifactId>
  891.         <version>${spring.version}</version>
  892.       </dependency>
  893.       <dependency>
  894.         <groupId>org.springframework</groupId>
  895.         <artifactId>spring-jdbc</artifactId>
  896.         <version>${spring.version}</version>
  897.       </dependency>
  898.       <dependency>
  899.         <groupId>org.springframework</groupId>
  900.         <artifactId>spring-tx</artifactId>
  901.         <version>${spring.version}</version>
  902.       </dependency>
  903.       <dependency>
  904.         <groupId>org.springframework</groupId>
  905.         <artifactId>spring-web</artifactId>
  906.         <version>${spring.version}</version>
  907.       </dependency>
  908.       <dependency>
  909.         <groupId>org.springframework</groupId>
  910.         <artifactId>spring-test</artifactId>
  911.         <version>${spring.version}</version>
  912.         <scope>test</scope>
  913.       </dependency>
  914.       <dependency>
  915.         <groupId>org.mybatis</groupId>
  916.         <artifactId>mybatis</artifactId>
  917.         <version>${mybatis.version}</version>
  918.       </dependency>
  919.       <dependency>
  920.         <groupId>org.mybatis</groupId>
  921.         <artifactId>mybatis-spring</artifactId>
  922.         <version>1.2.2</version>
  923.       </dependency>
  924.       <dependency>
  925.         <groupId>com.fasterxml.jackson.core</groupId>
  926.         <artifactId>jackson-databind</artifactId>
  927.         <version>${jackson.version}</version>
  928.       </dependency>
  929.       <dependency>
  930.         <groupId>com.fasterxml.jackson.core</groupId>
  931.         <artifactId>jackson-annotations</artifactId>
  932.         <version>${jackson.version}</version>
  933.       </dependency>
  934.       <dependency>
  935.         <groupId>com.fasterxml.jackson.module</groupId>
  936.         <artifactId>jackson-module-jaxb-annotations</artifactId>
  937.         <version>${jackson.version}</version>
  938.       </dependency>
  939.     </dependencies>
  940.   </dependencyManagement>
  941. </project>

Using fundamental annotations not included in Java SE

  • JCIP(Java Concurrency in Practice) annotations
    • GuardedBy, Immutable, NotThreadSafe, ThreadSafe
  • JSR 305(Annotations for Software Defect Detection) annotations
    • javax.annotation, javax.annotation.concurrent, javax.annotation.meta packages
    • includes JCIP annotations in javax.annotation.concurrent package
    • JSR305 API
  • JSR 330(Dependency Injection for Java) annotations
  • JSR 349(Bean Validation 1.1) annotations
  • Hibernate Validator


  ...
  <dependency>
    <!-- JSR 305 annotations which includes also JCIP annotations -->
    <groupId>com.google.code.findbugs</groupId>
    <artifactId>jsr305</artifactId>
    <version>3.0.1</version>
  </dependency>
  <dependency>
    <!-- JSR 330 annotations -->
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
  </dependency>
  <dependency>
    <!-- JSR 349 annotations -->
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
  </dependency>
  <dependency>
    <!-- Hibernate Validator -->
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.2.4.Final</version>
  </dependency>
  ...

Defining dependencies on Eclipse SWT and JFace with Maven 2

Artifacts of Eclipse SWT 3.3 and JFace 3.3 are registered central repository, but their versions have qualifiers such as "v3346", "v20070530" or "I20070606-0010" which are not aligned with Maven's version comparison definition.([Dependency Mediation and Conflict Resolution]) Nevertheless, Maven 3 seems to be able to resolve the dependencies including transitive ones. But Maven 2 and Maven's Ant Task which uses Maven 2 internally don't resolve the transitive dependencies correctly and throw exception. So, it you want to define dependencies on SWT and JFace with Maven 2 successfully, some transitive dependencies should be excluded and defined as direct ones like the following.


  <dependencies>
    <dependency>
      <groupId>org.eclipse.swt.win32.win32</groupId>
      <artifactId>x86</artifactId>
      <version>3.3.0-v3346</version>
      <type>jar</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.eclipse</groupId>
      <artifactId>jface</artifactId>
      <version>3.3.0-I20070606-0010</version>
      <type>jar</type>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <groupId>org.eclipse</groupId>
          <artifactId>swt</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.eclipse.core</groupId>
          <artifactId>commands</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jface</groupId>
      <artifactId>text</artifactId>
      <version>3.3.0-v20070606-0010</version>
      <type>jar</type>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <groupId>org.eclipse.core</groupId>
          <artifactId>runtime</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.eclipse</groupId>
          <artifactId>text</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.eclipse</groupId>
          <artifactId>swt</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.eclipse</groupId>
          <artifactId>jface</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.eclipse</groupId>
      <artifactId>text</artifactId>
      <version>3.3.0-v20070606-0010</version>
      <type>jar</type>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <groupId>org.eclipse.equinox</groupId>
          <artifactId>common</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <!-- redundant defintions of transitive dependencies to work with Maven 2 -->
    <dependency>
      <groupId>org.eclipse</groupId>
      <artifactId>swt</artifactId>
      <version>3.3.0-v3346</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.core</groupId>
      <artifactId>commands</artifactId>
      <version>3.3.0-I20070605-0010</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.core</groupId>
      <artifactId>runtime</artifactId>
      <version>3.3.100-v20070530</version>
      <exclusions>
        <exclusion>
          <groupId>org.eclipse.equinox</groupId>
          <artifactId>app</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.eclipse.equinox</groupId>
      <artifactId>common</artifactId>
      <version>3.3.0-v20070426</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.equinox</groupId>
      <artifactId>app</artifactId>
      <version>1.0.0-v20070606</version>
    </dependency>
  </dependencies>


Typical sample of Maven assembly descriptor

The location of deployment descriptors or configuration such as web.xml, log4j.xml can be adjusted using file element of assembly descriptor when they are not under WEB-INF or root directory of source directories.

<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

  <id>view</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <fileSets>
    <fileSet>
      <directory>${project.build.outputDirectory}</directory>
      <outputDirectory>/</outputDirectory>
      <useDefaultExcludes>true</useDefaultExcludes>
      <includes>
        <include>ambariplus/view/**/*.class</include>
      </includes>
      <filtered>false</filtered>
      <fileMode>0644</fileMode>
      <directoryMode>0755</directoryMode>
    </fileSet>
  </fileSets>
  <files>
    <file>
      <source>${project.build.outputDirectory}/ambariplus/view/view.xml</source>
      <outputDirectory>/</outputDirectory>
      <destName>view.xml</destName>
      <filtered>false</filtered>
      <lineEnding>unix</lineEnding>
      <fileMode>0644</fileMode>
    </file>
  </files>
</assembly>

Ant

Bare Ant build file using Maven-Ant tasks and Antelope

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project name="project.name" basedir="." default="echo.env" xmlns:artifact="antlib:org.apache.maven.artifact.ant"
  3.  xmlns:antelope="antlib:ise.antelope.tasks" xmlns:contrib="antlib:net.sf.antcontrib">
  4.  
  5.   <!-- Ant references :
  6.       Manual : http://ant.apache.org/manual/index.html
  7.       Path-like Structures : http://ant.apache.org/manual/using.html#path
  8.       Resource Collections : http://ant.apache.org/manual/Types/resources.html#collection
  9.  -->
  10.   <description>Title or descrption for this build file.</description>
  11.  
  12.   <property environment="env" />
  13.  
  14.   <!-- Define Maven-Ant tasks -->
  15.   <!-- For more on Maven-Ant tasks, refer http://maven.apache.org/ant-tasks/ -->
  16.   <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
  17.    uri="antlib:org.apache.maven.artifact.ant"
  18.    classpath="lib/maven-ant-tasks-2.1.3.jar">
  19.   </typedef>
  20.  
  21.   <artifact:dependencies pathId="ant.tasks.classpath">
  22.     <!-- libraries only necessary for Ant task not application. -->
  23.     <!-- Ant-Contrib tasks. For more, refer http://ant-contrib.sourceforge.net/tasks/ -->
  24.     <dependency groupId="ant-contrib" artifactId="ant-contrib" version="1.0b3" />
  25.     <!-- Antelope tasks. For more, refer http://antelope.stage.tigris.org/nonav/docs/manual/index.html -->
  26.     <dependency groupId="ise.antelope" artifactId="ant-antelope-tasks" version="3.5.0" />
  27.     <!-- SvnAnt tasks. For more, refer http://subclipse.tigris.org/svnant.html -->
  28.     <dependency groupId="org.tigris" artifactId="svnant" version="1.3.1" scope="system"
  29.      systemPath="${basedir}/lib/svnant.jar" />
  30.     <dependency groupId="org.tigris" artifactId="svn-client-adapter" version="0.9.102"
  31.      scope="system" systemPath="${basedir}/lib/svnClientAdapter.jar" />
  32.     <dependency groupId="org.tmatesoft.svnkit" artifactId="svnkit" version="1.8.10" />
  33.     <dependency groupId="org.tmatesoft.svnkit" artifactId="svnkit-javahl16" version="1.8.10" />
  34.     <!-- TestNG tasks. For more, refer http://testng.org/doc/ant.html -->
  35.     <dependency groupId="org.testng" artifactId="testng" version="6.8.21" />
  36.     <dependency groupId="org.mortbay.jetty" artifactId="jetty-runner" version="7.6.9.v20130131" />
  37.     <dependency groupId="org.eclipse.jetty" artifactId="jetty-jmx" version="7.6.9.v20130131" />
  38.     <dependency groupId="org.eclipse.jetty" artifactId="jetty-start" version="7.6.9.v20130131" />
  39.     <dependency groupId="org.umlgraph" artifactId="umlgraph" version="5.6.6" />
  40.     <dependency groupId="com.lunatech.jax-doclets" artifactId="doclets" version="0.10.0" />
  41.     <remoteRepository id="centeral2" url="http://repo2.maven.org/maven2/" />
  42.     <remoteRepository id="maven2-repository.dev.java.net" url="http://download.java.net/maven/2/" />
  43.     <remoteRepository id="tmatesoft-releases"
  44.      url="http://maven.tmatesoft.com/content/repositories/releases/" />
  45.     <remoteRepository id="evolvis-3rdparty" url="http://maven-repo.evolvis.org/3rdparty"
  46.      layout="default" />
  47.   </artifact:dependencies>
  48.  
  49.   <!-- Define Ant-Contrib tasks -->
  50.   <taskdef resource="net/sf/antcontrib/antlib.xml" uri="antlib:net.sf.antcontrib"
  51.    classpathref="ant.tasks.classpath" />
  52.  
  53.   <!-- Define Antelope tasks -->
  54.   <taskdef name="stringutil" classname="ise.antelope.tasks.StringUtilTask"
  55.    uri="antlib:ise.antelope.tasks" classpathref="ant.tasks.classpath" />
  56.   <taskdef name="if" classname="ise.antelope.tasks.IfTask"
  57.    uri="antlib:ise.antelope.tasks" classpathref="ant.tasks.classpath" />
  58.   <taskdef name="var" classname="ise.antelope.tasks.Variable"
  59.    uri="antlib:ise.antelope.tasks" classpathref="ant.tasks.classpath" />
  60.   <taskdef name="unset" classname="ise.antelope.tasks.Unset"
  61.    uri="antlib:ise.antelope.tasks" classpathref="ant.tasks.classpath" />
  62.  
  63.   <!-- Define SvnAnt tasks -->
  64.   <typedef resource="org/tigris/subversion/svnant/svnantlib.xml"
  65.    classpathref="ant.tasks.classpath" />
  66.  
  67.   <!-- Define TestNG tasks -->
  68.   <taskdef resource="testngtasks" classpathref="ant.tasks.classpath" />
  69.  
  70.   <artifact:pom id="project.pom" file="${basedir}/pom.xml" />
  71.   <artifact:dependencies pomRefId="project.pom" pathId="project.classpath" />
  72.  
  73.   <target name="echo.env" depends="query.version.revision">
  74.     <!-- @todo How to sort the list -->
  75.     <pathconvert pathsep="${line.separator}" refid="project.classpath" property="project.classpath.list">
  76.       <mapper type="regexp" from="(.*\\\.m2\\repository\\)?(.*)" to="  \2" />
  77.     </pathconvert>
  78.  
  79.     <echo>Defined properties : </echo>
  80.     <echoproperties />
  81.     <echo>
  82.     </echo>
  83.     <echo>Classpath : </echo>
  84.     <echo>${project.classpath.list}</echo>
  85.     <echo>Parsed Version : </echo>
  86.     <echo> major : ${ver.major}</echo>
  87.     <echo> minor : ${ver.minor}</echo>
  88.     <echo> incremental : ${ver.incremental}</echo>
  89.     <echo> tail : ${ver.tail}</echo>
  90.     <echo>Max revision under this project : ${revision.max}</echo>
  91.   </target>
  92.  
  93.   <target name="check.env">
  94.     <fail unless="env.MAVEN_HOME">Environment variable MAVEN_HOME should be specified properly.</fail>
  95.   </target>
  96.  
  97.   <target name="query.version.revision">
  98.     <svnant:svnSetting id="svn.setting" svnkit="true" javahl="false" />
  99.     <svnant:svn refid="svn.setting">
  100.       <!-- wcversion will set properties of repository.url, revision.max, committed.max and et al.
  101.        For more, refer http://subclipse.tigris.org/svnant/svntask.html#wcversion -->
  102.       <wcversion path="${basedir}" />
  103.     </svnant:svn>
  104.     <contrib:propertyregex property="ver.wo.snapshot" input="${project.pom.version}"
  105.      regexp="([0-9]+(\.[0-9]+)?(\.[0-9]+)?)" select="\1" defaultValue="0.0.0" />
  106.      
  107.     <contrib:propertyregex property="ver.major" input="${project.pom.version}"
  108.      regexp="([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(.+)?" select="\1" />
  109.     <contrib:propertyregex property="ver.minor" input="${project.pom.version}"
  110.      regexp="([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(.+)?" select="\2" defaultValue="0" />
  111.     <contrib:propertyregex property="ver.incremental" input="${project.pom.version}"
  112.      regexp="([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(.+)?" select="\3" defaultValue="0" />
  113.     <contrib:propertyregex property="ver.tail" input="${project.pom.version}"
  114.      regexp="([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(.+)?" select="\4" defaultValue="0" />
  115.  
  116.     <antelope:if name="ver.minor" value="">
  117.       <antelope:unset name="ver.minor" />
  118.       <property name="ver.minor" value="0" />
  119.     </antelope:if>
  120.     <antelope:if name="ver.incremental" value="">
  121.       <antelope:unset name="ver.incremental" />
  122.       <property name="ver.incremental" value="0" />
  123.     </antelope:if>
  124.   </target>
  125. </project>

Start and stop Jetty using Ant

  • build.xml
  1.   <property name="jetty.ver" value="7.6.9.v20130131"/>
  2.   <property name="jetty.port" value="8080"/>
  3.   <property name="jetty.jmxPort" value="3333"/>
  4.   <property name="jetty.stopPort" value="8087"/>
  5.   <property name="jetty.stopKey" value="stopnow"/>
  6.  
  7.   <artifact:dependencies pathId="jetty.classpath">
  8.     <dependency groupId="org.mortbay.jetty" artifactId="jetty-runner" version="${jetty.ver}"/>
  9.     <dependency groupId="org.eclipse.jetty" artifactId="jetty-start" version="${jetty.ver}"/>
  10.     <dependency groupId="org.eclipse.jetty" artifactId="jetty-jmx" version="${jetty.ver}"/>
  11.     <dependency groupId="org.eclipse.jetty" artifactId="jetty-test-webapp" type="war" version="7.0.0.M2"/>
  12.   </artifact:dependencies>
  13.  
  14.   <target name="jetty.runner.help"
  15.    description="Print command line help of jetty-runner">
  16.     <java jar="${org.mortbay.jetty:jetty-runner:jar}" fork="true">
  17.       <arg line="--help"/>  
  18.     </java>
  19.   </target>
  20.  
  21.   <target name="jetty.run"
  22.    description="Run Jetty server">
  23.     <java jar="${org.mortbay.jetty:jetty-runner:jar}" fork="true" spawn="false">
  24.       <jvmarg value="-Dcom.sun.management.jmxremote.port=${jetty.jmxPort}"/>
  25.       <jvmarg value="-Dcom.sun.management.jmxremote.ssl=false"/>
  26.       <jvmarg value="-Dcom.sun.management.jmxremote.authenticate=false"/>
  27.       <jvmarg value="-Djetty.host=127.0.0.1"/>
  28.       <jvmarg value="-Djetty.port=${jetty.port}"/>
  29.       <arg value="--log"/>
  30.       <arg value="${basedir}/target/jetty-yyyy_mm_dd.log"/>
  31.       <arg value="--stop-port"/>
  32.       <arg value="${jetty.stopPort}"/>
  33.       <arg value="--stop-key"/>
  34.       <arg value="${jetty.stopKey}"/>
  35.       <arg value="--jar"/>
  36.       <arg value="${org.eclipse.jetty:jetty-jmx:jar}"/>
  37.       <arg value="--config"/>
  38.       <arg value="${basedir}/src/main/webapp/WEB-INF/jetty.xml"/>
  39.       <arg value="${basedir}/src/main/webapp"/>
  40.       <!-- <arg value="${org.eclipse.jetty:jetty-test-webapp:war}"/> -->
  41.     </java>
  42.   </target>
  43.  
  44.   <target name="jetty.stop"
  45.    description="Stop Jetty server">
  46.     <java jar="${org.eclipse.jetty:jetty-start:jar}" fork="true">
  47.       <jvmarg value="-DSTOP.PORT=${jetty.stopPort}"/>
  48.       <jvmarg value="-DSTOP.KEY=${jetty.stopKey}"/>
  49.       <arg value="--stop"/>
  50.     </java>
  51.   </target>
  • jetty.xml
  1. <?xml version="1.0"?>
  2. <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
  3.  
  4. <Configure id="Server" class="org.eclipse.jetty.server.Server">
  5.  
  6.   <Set name="ThreadPool">
  7.     <!-- Default queued blocking threadpool -->
  8.     <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
  9.       <Set name="minThreads">10</Set>
  10.       <Set name="maxThreads">200</Set>
  11.       <Set name="detailedDump">false</Set>
  12.     </New>
  13.   </Set>
  14.  
  15.   <Call name="addConnector">
  16.     <Arg>
  17.       <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
  18.         <Set name="host"><SystemProperty name="jetty.host" default="127.0.0.1"/></Set>
  19.         <Set name="port"><SystemProperty name="jetty.port" default="8080" /></Set>
  20.         <Set name="maxIdleTime">300000</Set>
  21.         <Set name="Acceptors">2</Set>
  22.         <Set name="statsOn">false</Set>
  23.         <Set name="confidentialPort">8443</Set>
  24.         <Set name="lowResourcesConnections">20000</Set>
  25.         <Set name="lowResourcesMaxIdleTime">5000</Set>
  26.       </New>
  27.     </Arg>
  28.   </Call>
  29.  
  30.   <Set name="handler">
  31.     <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
  32.       <Set name="handlers">
  33.         <Array type="org.eclipse.jetty.server.Handler">
  34.           <Item>
  35.             <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection" />
  36.           </Item>
  37.           <Item>
  38.             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler" />
  39.           </Item>
  40.         </Array>
  41.       </Set>
  42.     </New>
  43.   </Set>
  44.  
  45.   <Set name="stopAtShutdown">true</Set>
  46.   <Set name="sendServerVersion">true</Set>
  47.   <Set name="sendDateHeader">true</Set>
  48.   <Set name="gracefulShutdown">1000</Set>
  49.   <Set name="dumpAfterStart">false</Set>
  50.   <Set name="dumpBeforeStop">false</Set>
  51. </Configure>


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  4.  version="2.5">
  5.  
  6.   <servlet>
  7.     <servlet-name>defaultServlet</servlet-name>
  8.     <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
  9.     <init-param>
  10.       <param-name>useFileMappedBuffer</param-name>
  11.       <param-value>false</param-value>
  12.     </init-param>
  13.     <load-on-startup>0</load-on-startup>
  14.   </servlet>
  15.  
  16.   <servlet-mapping>
  17.     <servlet-name>defaultServlet</servlet-name>
  18.     <url-pattern>/</url-pattern>
  19.   </servlet-mapping>
  20.  
  21.   <welcome-file-list>
  22.     <welcome-file>index.html</welcome-file>
  23.   </welcome-file-list>
  24.   <error-page>
  25.     <error-code>404</error-code>
  26.     <location>/404.html</location>
  27.   </error-page>
  28.  
  29. </web-app>

Generate Javadoc using Ant and Maven

  1. <project name="ambari.server.ext" basedir="."
  2.         xmlns:artifact="antlib:org.apache.maven.artifact.ant">
  3.  
  4.   <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
  5.          uri="antlib:org.apache.maven.artifact.ant">
  6.     <classpath>
  7.         <pathelement location="lib/maven-ant-tasks-2.1.3.jar"/>
  8.     </classpath>
  9.   </typedef>
  10.  
  11.   <artifact:dependencies pathId="ambari.server.classpath">
  12.     <pom file="${ambari.server.project.dir}/pom.xml"/>
  13.   </artifact:dependencies>
  14.  
  15.   <artifact:dependencies pathId="extra.classpath">
  16.     <dependency groupId="org.umlgraph" artifactId="umlgraph" version="5.6.6"/>
  17.   </artifact:dependencies>
  18.  
  19.   <target name="generateAmbariJavadoc" description="generate Java API documentation for Ambari">
  20.     <javadoc destdir="${ambari.server.project.dir}/target/javadoc"
  21.      maxmemory="256m" access="private" encoding="utf-8" docencoding="utf-8"
  22.      windowtitle="Apache Ambari Java API" doctitle="Apache Ambari Java API"
  23.       version="true" use="true" author="true"   splitindex="true"
  24.      nodeprecated="false" notree="false" noindex="false" nohelp="false" nonavbar="false"
  25.      linksource="yes">
  26.       <sourcepath>
  27.         <pathelement location="${ambari.server.project.dir}/src/main/java"/>
  28.       </sourcepath>
  29.       <classpath refId="ambari.server.classpath"/>
  30.       <doclet name="org.umlgraph.doclet.UmlGraphDoc" path="${org.umlgraph:umlgraph:jar}">
  31.         <param name="-inferrel"/>
  32.         <param name="-hide" value="(java|javax).*"/>
  33.         <param name="-collpackages" value="java.util.*"/>
  34.         <param name="-link" value="http://docs.oracle.com/javase/6/docs/api/"/>
  35.         <param name="-link" value="http://docs.oracle.com/javaee/6/api/"/>
  36.         <param name="-link" value="http://jsr-305.googlecode.com/svn/trunk/javadoc/"/>
  37.         <param name="-link" value="http://docs.jboss.org/hibernate/beanvalidation/spec/1.1/api/"/>
  38.         <param name="-link" value="http://docs.jboss.org/hibernate/validator/5.2/api/"/>
  39.         <param name="-link" value="http://commons.apache.org/proper/commons-lang/javadocs/api-3.3.2/"/>
  40.         <param name="-link" value="http://google-guice.googlecode.com/svn/tags/3.0/javadoc/packages.html"/>
  41.         <param name="-link" value="http://docs.spring.io/spring/docs/4.0.x/javadoc-api/"/>
  42.         <param name="-link" value="https://jersey.java.net/apidocs/1.11/jersey/"/>
  43.       </doclet>
  44.       <link href="http://docs.oracle.com/javase/6/docs/api/"/>
  45.       <link href="http://docs.oracle.com/javaee/6/api/"/>
  46.       <link href="http://jsr-305.googlecode.com/svn/trunk/javadoc/"/>
  47.       <link href="http://docs.jboss.org/hibernate/beanvalidation/spec/1.1/api/"/>
  48.       <link href="http://docs.jboss.org/hibernate/validator/5.2/api/"/>
  49.       <link href="http://commons.apache.org/proper/commons-lang/javadocs/api-3.3.2/"/>
  50.       <link href="http://commons.apache.org/proper/commons-collections/javadocs/api-release/"/>
  51.       <link href="http://google-guice.googlecode.com/svn/tags/3.0/javadoc/packages.html"/>      
  52.       <link href="http://docs.spring.io/spring/docs/4.0.x/javadoc-api/"/>
  53.       <link href="https://jersey.java.net/apidocs/1.11/jersey/"/>
  54.     </javadoc>
  55.    </target>

It could be better to use deployed artifact instead of the pom.

  1. <project name="thirdstage.red5.build" basedir="." default="echo.env"
  2.   xmlns:artifact="antlib:org.apache.maven.artifact.ant">
  3.  
  4.    <property environment="env"/>
  5.  
  6.    <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
  7.            uri="antlib:org.apache.maven.artifact.ant">
  8.       <classpath>
  9.          <pathelement location="${basedir}/lib/maven-ant-tasks-2.1.3.jar"/>
  10.       </classpath>
  11.    </typedef>
  12.  
  13.    <artifact:dependencies pathId="classpath.red5">
  14.       <dependency groupId="org.red5" artifactId="red5-io" version="1.0.5-RELEASE">
  15.          <exclusion groupId="org" artifactId="jaudiotagger"/>
  16.       </dependency>
  17.       <dependency groupId="org.red5" artifactId="red5-server-common" version="1.0.5-RELEASE">
  18.          <exclusion groupId="org" artifactId="jaudiotagger"/>
  19.       </dependency>
  20.       <dependency groupId="org.red5" artifactId="red5-service" version="1.0.5-RELEASE">
  21.          <exclusion groupId="org" artifactId="jaudiotagger"/>
  22.       </dependency>
  23.       <dependency groupId="org.red5" artifactId="red5-server" version="1.0.5-RELEASE">
  24.          <exclusion groupId="org" artifactId="jaudiotagger"/>
  25.       </dependency>
  26.       <dependency groupId="org.red5" artifactId="red5-client" version="1.0.5-RELEASE">
  27.          <exclusion groupId="org" artifactId="jaudiotagger"/>
  28.       </dependency>
  29.       <remoteRepository id="grails" url="https://repo.grails.org/grails/repo/">
  30.          <snapshots checksumPolicy="warn" updatePolicy="never"/>
  31.          <releases checksumPolicy="warn" updatePolicy="never"/>
  32.       </remoteRepository>
  33.    </artifact:dependencies>
  34.  
  35.    <target name="echo.env">
  36.       <echo>Defined properties : </echo>
  37.       <echoproperties />
  38.    </target>
  39.  
  40.    <target name="generate.javadoc" description="Generate Javadoc for Red5 projects">
  41.       <javadoc destdir="${basedir}/target/javadoc"
  42.         maxmemory="256m" access="private" encoding="utf-8" docencoding="utf-8"
  43.               windowtitle="Red5 API" doctitle="Red5 API"
  44.               version="true" use="true" author="true" splitindex="true"
  45.               nodeprecated="false" notree="false" noindex="false" nohelp="false" nonavbar="false">
  46.          <sourcepath>
  47.             <pathelement location="${basedir}/../red5-io/src/main/java"/>
  48.             <pathelement location="${basedir}/../red5-server-common/src/main/java"/>
  49.             <pathelement location="${basedir}/../red5-service/src/main/java"/>
  50.             <pathelement location="${basedir}/../red5-server/src/main/java"/>
  51.             <pathelement location="${basedir}/../red5-client/src/main/java"/>
  52.          </sourcepath>
  53.          <classpath refid="classpath.red5"/>
  54.          <link href="http://docs.oracle.com/javase/6/docs/api/"/>
  55.          <link href="http://docs.oracle.com/javaee/6/api/"/>
  56.          <link href="https://mina.apache.org/mina-project/apidocs/"/>
  57.          <link href="http://ehcache.org/apidocs/2.6.9/"/>
  58.       </javadoc>
  59.    </target>
  60. </project>

Scala

Waiting Enter key press on the console

  1.    ...
  2.     var cnt = 0
  3.     var keyed = false
  4.     do {
  5.       cnt = System.in.available()
  6.       if (cnt >= 1) keyed = true
  7.       else Thread.sleep(500)
  8.     } while (!keyed)
  9.  
  10.     while (cnt > 0) {
  11.       System.in.read()
  12.       cnt -= cnt
  13.     }
  14.     ...

C, C++

Pointer, Address Operator and Indirection(Dereferencing) Operator

The following definitions and explanations are from the ANCI C specicifation

  • Address and indirection operators
    • Constraints
      1. The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.
      2. The operand of the unary * operator shall have pointer type.
    • Semantics
      1. The unary & operator yields the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. Otherwise, the result is a pointer to the object or function designated by its operand.
      2. The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.

The following code snippet is from the book 'The C Programming Language'

int x = 1, y =2, z[10]
int *p;                   /* p is a pointer to int */

p = &x;                   /* p now points to x */
y = *p;                   /* y is now 1 */
*p = 0;                   /* x is now 0 */
p = &z[0];                /* p now points to z[0] */

Developing Visual C++ application using Eclipse CDT

Visual C++ 2008 and CDT

Visual C++ project : Environment Variables
  • In case of Visual Studio 2008 on Windows 7 64bit, the environment variable are defined at a batch file called from the C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat.
  • Related files
    • C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat
    • C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat
    • C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat
  • Defined Variables
Environment Variable Value Remarks
VSInstallDir C:\Program Files (x86)\Microsoft Visual Studio 9.0
VCInstallDir C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC
WindowsSdkDir C:\Program Files\Microsoft SDKs\Windows\v6.0A\ HKEY_CURRENT_USER\Software\Microsoft\Microsoft SDKs\Windows

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A

FrameworkDir C:\Windows\Microsoft.NET\Framework
FrameworkVersion v2.0.50727
FrameworkSDKDir  ?
FxCopDir  ?
ProgramFiles C:\Program Files Predefined by Windows 7
SystemRoot C:\Windows Predefined by Windows 7
Visual C++ project : Build configuration base
  • Implicit base path (PATH)
$(VCInstallDir)\bin
$(WindowsSdkDir)\bin
$(VSInstallDir)Common7\Tools\bin
$(VSInstallDir)Common7\tools
$(VSInstallDir)Common7\ide
$(ProgramFiles)\HTML Help Workshop
$(FrameworkSDKDir)bin
$(FrameworkDir)$(FrameworkVersion)
$(VSInstallDir)
$(SystemRoot)\SysWow64
$(FxCopDir)
$(PATH)
  • Implicit base include path (INCLUDE)
$(VCInstallDir)include
$(VCInstallDir)atlmfc\include
$(WindowsSdkDir)\include
$(FrameworkSDKDir)include
  • Implicit LIBPATH
$(FrameworkDir)$(FrameworkVersion)
$(VCInstallDir)atlmfc\lib
$(VCInstallDir)lib
  • Implicit LIB
$(VCInstallDir)lib
$(VCInstallDir)atlmfc\lib
$(VCInstallDir)atlmfc\lib\i386
$(WindowsSdkDir)\lib
$(FrameworkSDKDir)lib
$(VSInstallDir)
$(VSInstallDir)lib
CDT Configuration > build variables
Build Variable Value Remarks
VSInstallDir ${env_var:VS_INSTALL_DIR}
VCInstallDir ${env_var:VC_INSTALL_DIR}
WindowsSdkDir ${env_var:WINDOWS_SDK_DIR}
FrameworkDir ${env_var:FRAMEWORK_DIR}
FrameworkVersion ${env_var:FRAMEWORK_VERSION}
CDT Configuration > Environment
Environment Variable Value Remarks
INCLUDE ${VCInstallDir}\include;${VCInstallDir}\atlmfc\include;${WindowsSdkDir}\include;${env_var:INCLUDE}
JAVA_HOME ${env_var:JAVA_32_HOME}
LIB ${VCInstallDir}\lib;${VCInstallDir}\atlmfc\lib;${VCInstallDir}\atlmfc\lib\i386;${WindowsSdkDir}\lib;${FrameworkSDKDir}\lib;${VSInstallDir};${VSInstallDir}\lib;${env_var:LIB}
LIBPATH ${FrameworkDir}\${FrameworkVersion};${VCInstallDir}\atlmfc\lib;${VCInstallDir}\lib;${env_var:LIBPATH}
PATH ${VCInstallDir}\bin;${WindowsSdkDir}\bin;${VSInstallDir}\Common7\Tools\bin;${VSInstallDir}\Common7\Tools;${VSInstallDir}\Common7\IDE;${ProgramFiles}\HTML Help Workshop;${FrameworkDir}\${FrameworkVersion};${VSInstallDir};${SystemRoot}\SysWow64;${VCInstallDir}\VCPackages;${env_var:PATH}

Visual C++ 2010 Express

Visual C++ Build Configuration Sample : Apache Log4cxx

  • As of Log4cxx 0.10.0

Compile

  • Debug build
/Od /I "..\src\main\include" /I "..\..\apr\include" /I "..\..\apr-util\include" /D "_DEBUG" /D "_USRDLL" /D "DLL_EXPORTS" /D "LOG4CXX" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "WIN32" /D "_VC80_UPGRADE=0x0600" /D "_WINDLL" /FD /EHsc /RTC1 /MDd /Fp".\Debug/log4cxx.pch" /Fo".\Debug/" /Fd".\Debug/" /nologo /c /Zi /TP /errorReport:prompt
  • Release build
/O2 /Ob1 /I "..\src\main\include" /I "..\..\apr\include" /I "..\..\apr-util\include" /D "NDEBUG" /D "_USRDLL" /D "DLL_EXPORTS" /D "LOG4CXX" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "WIN32" /D "_VC80_UPGRADE=0x0600" /D "_WINDLL" /GF /FD /EHsc /MD /Gy /Fp".\Release/log4cxx.pch" /Fo".\Release/" /Fd".\Release/" /nologo /c /TP /errorReport:prompt

Link

  • Debug build
/OUT:".\Debug/log4cxx.dll" /INCREMENTAL:NO /NOLOGO /DLL /MANIFEST /MANIFESTFILE:".\Debug\log4cxx.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:".\Debug/log4cxx.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /IMPLIB:".\Debug/log4cxx.lib" /ERRORREPORT:PROMPT ADVAPI32.LIB WS2_32.LIB MSWSOCK.LIB SHELL32.LIB ODBC32.LIB  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "..\..\apr-util\libd\aprutil-1.lib" "..\..\apr-util\xml\expat\lib\libd\xml.lib" "..\..\apr\libd\apr-1.lib"
  • Release build
/OUT:".\Release/log4cxx.dll" /INCREMENTAL:NO /NOLOGO /DLL /MANIFEST /MANIFESTFILE:".\Release\log4cxx.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /PDB:".\Release/log4cxx.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /IMPLIB:".\Release/log4cxx.lib" /ERRORREPORT:PROMPT ADVAPI32.LIB WS2_32.LIB MSWSOCK.LIB SHELL32.LIB ODBC32.LIB  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "..\..\apr-util\libd\aprutil-1.lib" "..\..\apr-util\xml\expat\lib\libd\xml.lib" "..\..\apr\libd\apr-1.lib"

JavaScript

Sample to understand scoping and hoisting of JavaScript

The following sample is part of QUnit script to confirm the scope and hoisting of JavaScript explained at http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

test("scope test 1", function(){
  //For explanation, refer http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

  var foo = 1;

  function bar(){
    var bar = 1;

    if(!foo){ //this block will be EXECUTED. !!!
      var foo = 10; //at interpret time, declare 'var foo' at the 1st line of bar().
      bar = 10;
    };
    return bar;
  };

  function baz(){
    var baz = 1;
    if(foo){ //this block will NOT be executed. !!!
      var foo = 10; //at interpret time, declare 'var foo' at the 1st line of baz().
      baz = 10;
    };
    return baz;
  };

  function quz(){
    var a = 1;
    var quz = 1;
    function a(){ quz = 10; }; //fail to override a, but no error.
    try{
      a(); //will throw error at this line.
    }catch(e){ quz = 100; };
    return quz;
  };

  function kix(){
    b = 1; //global scope
    var kix = 1;
    function b(){ kix = 10; }; //fail to override but no error;
    kix = 100;
    try{
      b(); //will throw error at this line.
    }catch(e){ kix += 1; }
    return kix;
  };

  equal(bar(), 10);
  equal(baz(), 1);
  equal(quz(), 100);
  equal(kix(), 101);
  equal(foo, 1);
});


Creating global object in IIEF

The following sample is a littel modification of d3.js which shows :

  • How to encapsulate the global object using IIEF and closuer.
  • Exposing the object into global in case of AMD, RequireJS or non-AMD environment.
  • Prevent the misuse or unintended pollution on window or undefined.

But the following code doesn't show proper contents in Eclipse Outline view. Need more elaboration.

(function(window, $, undefined){
   "use strict";

   var d3 = { version: "3.4.2" };

   //...

  if (typeof define === "function" && define.amd) {
    define(d3);
  } else if (typeof module === "object" && module.exports) {
    module.exports = d3;
  } else {
    window.d3 = d3;  
  }
)(window, window.jQuery);

Basic coordination of chart with D3.js

Use more semantic variables of dimensions, paddings, area, domains or scales as objects like the following typical example. Note that some properties of areas.x, area.y, domains.x or domains.y are not objects but arrays to make consistency with the syntax of d3.js.

  var dimensions = {width : 800, height : 400};
  var paddings = {top : 20, right : 30, bottom : 40, left : 50};
  var area = {
    x : [paddings.left, dimensions.width - paddings.right],
    y : [dimensions.height - paddings.bottom, paddings.top]  //large value first !
  }
  var domains = {
    x : [new Date(2014,4,1,0,0,0), new Date(2014,4,1,0,1,0)],
    y : [0, 100]
  }
  var r = 3;
  var data = [];

  //create scales
  var scales = {
    x : d3.time.scale().range(area.x).domain(domains.x),
    y : d3.scale.linear().range(area.y).domain(domains.y)
  }

  //create pannel
  d3.select("#chart").insert("svg", "div")
    .attr("width", dimensions.width)
    .attr("height", dimensions.height);
    //.style("background-color", "white");

  var axis = {
    x : d3.svg.axis().scale(scales.x).orient("bottom").ticks(10),
    y : d3.svg.axis().scale(scales.y).orient("left").ticks(10)
  }

  d3.select("#chart svg").append("g")
    .classed("axis x", true)
    .attr("transform", "translate(0, " + area.y[0] + ")")
    .call(axis.x);

  d3.select("#chart svg").append("g")
    .classed("axis y", true)
    .attr("transform", "translate(" + area.x[0] + ", 0)")
    .call(axis.y);

HTML and CSS

Basic templates

HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Standard Template</title>
</head>
<body>

</body>
</html>

CSS

body {
  font-family: "맑은 고딕", Georgia, Verdana, sans-serif;
  font-size: 1.0em;
  line-height:1.5;
  margin-left:2.0em;
  counter-reset: step-h3;
}

pre, code, tt {
  font-family: Consolas,monospace,Courier;
  font-size: 1.0em;
  line-height: 1.3 !important;
}

table { border-collapse: collapse; }
th, td { border: 1px solid #999;padding: 0.2em; }

h1, h2, h3, h4, h5, h6 {
  font-family: "맑은 고딕", Helvetica, "Trebuchet MS", Verdana;
  margin-top:1.0em;
  margin-bottom:1px;
  padding-top:0px;
  padding-bottom:0px;
  -webkit-font-smoothing: antialiased;
}

h1 { font-size:1.8em; }
h2 { font-size:1.5em; }
h3 { font-size:1.4em; }
h4 { font-size:1.3em; }
h5 { font-size:1.2em; }
h6 { font-size:1.15em; }

h3:before {
  content: counter(step-h3) ". ";
  counter-increment: step-h3;
  counter-reset: step-h4;
}
h4:before {
  content: counter(step-h3) ". " counter(step-h4) ". ";
  counter-increment: step-h4;
  counter-reset: step-h5;
}
h5:before {
  content: counter(step-h3) ". " counter(step-h4) ". " counter(step-h5) ". ";
  counter-increment: step-h5;
  counter-reset: step-h6;
}
h6:before {
  content: counter(step-h3) ". " counter(step-h4) ". " counter(step-h5) ". " counter(step-h6) ". ";
  counter-increment: step-h6;
}

div.syntaxhighlighter{
  padding-top:0.5em;
  padding-bottom:0.5em;
  padding-left:0.5em;
  border:thin solid lightgray;
}
div.syntaxhighlighter div.line{
  line-height:1.5 !important;
}

XML, XSLT, XPath, XQuery

Useful or intelligent expressions of XQuery

Think over the following expressions. What are they? These are from the book "XSLT Coookbook" by Sal Mangano.

(50,45,40,34,32,29,-1)[(index-of((('XXL', 'XL', 'L', 'M', 'S', 'XS')), size), 7)[1]]

The following iterates just n times not n2 times.

for $pos in 1 to count($sequence), $item in $sequence[$pos] return $item , $pos

Use positional variable with order by

Positional variables are calculated before oder by process. If you want to use positional variables after ordering, you can make additional query with positional variables on ordered query like inline query of SQL.

  1. <id-list ordered='true'>
  2.    for $y at $i in (for $x in $doc//@id
  3.       order by string($x)
  4.       return $x)
  5.    return <id count='{$i}'>{string($y)}</id>
  6. </id-list>

Regex

Normalizing start tags of XML

To remove unnecessary white-spaces or line-breaks inside start tags, you can apply two regex pattern nested. In the following JavaScript sample, the tag name is assumed to be more typical than the somewhat complex pattern the XML spec defines.

  1.   function normalizeXmlTags(str){
  2.  
  3.     var str1, str2;
  4.     var re, re1, re2;
  5.     var result;
  6.  
  7.     //normalize start tag including attribute values
  8.     //refer http://www.w3.org/TR/REC-xml/#AVNormalize
  9.     //the most common form of xs:name : [A-Za-z_:][-\w:.]+ (http://www.w3.org/TR/xml/#d0e804)
  10.     re1 = /<\s*([A-Za-z_:][-\w:.]+)([^<>]*[^\/<>])?(\/)?>/g;
  11.     re2 = /\s*([A-Za-z_:][-\w:.]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
  12.  
  13.     str1 = str.replace(re1, function(match, p1, p2, p3, offset, string) {
  14.       p2 = (p2 || "").trim();
  15.  
  16.       str2 = p2.replace(re2, function(match, p1, p2, p3, offset, string) {
  17.         result = " " + p1 + "=";
  18.         // only one of p2 or p3 always undefined
  19.         if (p2) {
  20.           result += "\"" + p2.trim() + "\"";
  21.         } else if (p3) {
  22.           result += "'" + p3.trim() + "'";
  23.         } else {/*error */ }
  24.  
  25.         return result;
  26.       });
  27.  
  28.       return "<" + p1 + str2 + (p3 || "") + ">";
  29.     });
  30.  
  31.     //normalize the end tag
  32.     re = /<\/\s*([A-Za-z_:][-\w:.]+)\s*>/g;
  33.     return str1.replace(re, "</$1>");
  34.   };

SQL

Hierarchical queries

There are two types of hierarchical queries handling tree structure data in adjacency list model (table has recursive relationship using foreign key on parent_id column). One is (START WITH) CONNECT BY clause provided by Oracle and the other is recursive WITH clause(recursive common table expressions). Although CONNECT BY clause is much more intuitive, robust and simple, WITH clause is ANSI-SQL standard syntax.

CONNECT BY clause

  1. SELECT ~
  2. FROM ~
  3. WHERE ~
  4. START WITH parent_id IS NULL
  5. CONNECT BY PRIOR id = parent_id

Recursive WITH clause

Examples by database

The structure of the table for the example statements below is defined by the following DDL.

  1. CREATE TABLE category(
  2.  id varchar2(10) NOT NULL,
  3.  name varchar2(60) NOT NULL,
  4.  parent_id varchar2(10),
  5.  seq NUMBER(5, 0),
  6.  descn varchar2(2000),
  7.  CONSTRAINT pk_category PRIMARY KEY (id),
  8.  CONSTRAINT fk_cateogry_1 FOREIGN KEY (parent_id) REFERENCES category(id)
  9. );
Oracle 9i or higher

The basic query is :

  1. SELECT id, name, parent_id, seq, descn,
  2. FROM category
  3. START WITH parent_id IS NULL
  4. CONNECT BY PRIOR id = parent_id

Oracle 9i provides LEVEL pseudo-column, SYS_CONNECT_BY function and ORDER SIBLINGS BY clause which can be used in hierarchical queries.

  1. SELECT id, name, parent_id, seq, LEVEL, descn,
  2.        SYS_CONNECT_BY_PATH(id, '//') AS id_path,
  3.        SYS_CONNECT_BY_PATH(name, '//') AS name_path
  4. FROM category
  5. START WITH parent_id IS NULL
  6. CONNECT BY PRIOR id = parent_id
  7. ORDER SIBLINGS BY seq, name

Oracle 10g provides additional CONNECT_BY_ISLEAF pseudo-column, CONNECT_BY_ISCYCLE pseudo-column and CONNECT BY NOCYCLE.

SELECT id, name, parent_id, seq, LEVEL, descn,
       SYS_CONNECT_BY_PATH(id, '//') AS id_path,
       SYS_CONNECT_BY_PATH(name, '//') AS name_path,
       CONNECT_BY_ISLEAF AS is_leaf
FROM category
START WITH parent_id IS NULL
CONNECT BY NOCYCLE PRIOR id = parent_id AND LEVEL >= 5
ORDER SIBLINGS BY seq, name
Microsoft SQL Server 2005 or higher

The basic hierarchical query is

WITH v_category("id", "name", "level", parent_id) AS (
   SELECT "id", "name", 1 AS "level", parent_id
   FROM category
   WHERE id IS NULL
   UNION ALL
   SELECT a."id", b."level" + 1, a.parent_id
   FROM category AS a INNER JOIN v_category AS b ON a.parent_id = b."id"
)
SELECT "id", "name", "level", parent_id
FROM v_category

Readings

misc

  • MySQL (up to 6.0, latest version) still doesn't support hierarchical query.

FFmpeg

Querying information on a media

ffprobe -unit -pretty -print_format json ^
-show_format -show_streams -show_programs -show_chapters ^
-show_program_version  -show_library_versions -show_versions ^
matrix2-superbowltrailer640_dl.mov

Encoding a video using H.264

ffmpeg -i matrix2-superbowltrailer640_dl.mov ^
-an -c:v libx264 -r 30 -aspect 16:9 -bf 0 -refs 1 ^
-pix_fmt yuvj420p -preset veryslow -profile:v main -level 4.1 ^
-format avi matrix2-superbowltrailer640_dl.avi