Java 프로그램의 셸 스크립트 패키지 소개

10553 단어 JavaShell
많은 자바 프로젝트에서 프로그램 사용자 정의 매개 변수가 자바 명령을 호출하는 패키지 셸 스크립트를 자주 볼 수 있다.예를 들어,
 

$ANT_HOME/bin/ant, $GROOVY_HOME/bin/groovy
, 심지어 TimeMachine Scheduler 프로그램에서도 볼 수 있습니다
 

$TIMEMACHINE_HOME/bin/scheduler.sh
이 포장 스크립트를 작성하는 것은 매우 지루하고 실수하기 쉽다.대부분의 문제는 프로그램에 정확한classpath를 설정하는 것이다.만약 당신이 한 회사를 위해 내부 프로젝트를 개발하고 있다면, 당신은 복잡한 경로와 환경 변수 문제를 멀리할 수 있다.그러나 개원 프로젝트에 대해 사람들은 포장을 더욱 유연하고 통용해야 한다.대다수는 심지어 제공했다.bat 버전.Windows DOS는 프로젝트 스크립트의 요구를 충족시키지 못하는 야만적이고 제한된 단말기입니다.그래서 저는 항상 다른 사람들이 가능한 한 Cygwi를 많이 사용하도록 격려합니다.적어도 그것은 진실한 bash 셸을 갖추고 있다.다른 흔히 볼 수 있는 문제는 포장이 곧 통제를 잃을 뿐만 아니라 프로젝트 곳곳에 불필요한 스크립트가 많이 생길 수 있다는 것이다.
run-java 포장 스크립트 소개
$TIMEMACHINE_HOME/bin/scheduler.sh의 코드는 같은 디렉터리에서 run-java 스크립트를 순환적으로 호출하는 것을 볼 수 있습니다.
 

DIR=$(dirname $0)
SCHEDULER_HOME=$DIR/..
$DIR/run-java -Dscheduler.home="$SCHEDULER_HOME" timemachine.scheduler.tool.SchedulerServer "$@"
보시다시피 저희run-java는 -D 옵션을 사용할 수 있습니다. 뿐만 아니라 -cp 옵션도 사용할 수 있습니다!그리고 메인클래스 뒤에서 이 옵션을 지정할 수 있습니다!이렇게 하면run-java가 다른 스크립트에 포장되고 시스템 속성과classpath를 추가할 수 있습니다.
예를 들어 Time Machine에는 Groovy 라이브러리가 포함되어 있기 때문에 간단하게 이렇게 호출할 수 있습니다
 

groovy:$TIMEMACHINE_HOME/bin/run-java groovy.ui.GroovyMain test.groovy

전체 지점을 다시 다운로드할 필요가 없습니다.
모든 디렉터리에서 편리하게 사용할 수 있습니다. 디렉터리를 확인한 다음lib 디렉터리에 있는jar 패키지를 자동으로 불러올 수 있습니다.Groovy를 실행하기 위해 더 많은jar 패키지를 추가하려면 다음과 같이 -cp 옵션을 사용할 수 있습니다.
 

$TIMEMACHINE_HOME/bin/run-java -cp "$HOME/apps/my-app/lib/*" groovy.ui.GroovyMain test.groovy
보통 자바classpath를 설정하는 데 조심하지 않으면 오류가 자주 발생하지만run-java를 사용하면 미리 실행할 수 있습니다.
 

RUN_JAVA_DRY=1 $TIMEMACHINE_HOME/bin/run-java -cp "$HOME/apps/my-app/lib/*" groovy.ui.GroovyMain test.groovy
명령 알림 줄에서 위의 코드를 실행하기만 하면 됩니다.모든 옵션과 파라미터를 포함하는 자바 명령을 출력합니다.
run-script에는 다른 옵션도 많이 포함되어 있습니다. 설명을 보면 알 수 있습니다.현재 스크립트는 모든 Linux bash와 Windows Cygwin에서 실행할 수 있습니다.
개발 중에 Maven을 통해run-java를 사용합니다.
위에서 언급한 예에 따라 프로젝트 발표 구조는 다음과 같다고 가정합니다.

$TIMEMACHINE_HOME
 +- bin/run-java
 +- lib/*.jar

그런데 개발 과정에서 목록은 어떻게 될까요?흔히 볼 수 있는 용례는 target/classes에서 최신 컴파일된 코드를 실행하는 것이지 전체 프로젝트를 포장하거나 발표하는 것이 아니다.너도 마찬가지로 이런 상황에서run-java를 사용할 수 있다.우선, 간단하게 bin/run-java를 프로젝트에 추가한 다음 실행합니다
 

mvn compile dependency:copy-dependencies
target/dependency에서 모든jar 파일을 생성합니다.이것만 하면 돼.run-java는 이 디렉터리들을 자동으로 검사하고mainclass에 정확한classpath를 만듭니다.
만약 당신이 Eclipse를 사용하여 개발한다면, 당신의 target/classes 디렉터리는 항상 업데이트될 것입니다. run-java는 당신의 프로젝트 개발의 보물이 될 것입니다.
run-java 패키지 스크립트 가져오기
 

#!/usr/bin/env bash
#
# Copyright 2012 Zemian Deng
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
 
# A wrapper script that run any Java6 application in unix/cygwin env.
#
# This script is assumed to be located in an application's "bin" directory. It will
# auto resolve any symbolic link and always run in relative to this application
# directory (which is one parent up from the script.) Therefore, this script can be
# run any where in the file system and it will still reference this application
# directory.
#
# This script will by default auto setup a Java classpath that picks up any "config"
# and "lib" directories under the application directory. It also will also add a
# any typical Maven project output directories such as "target/test-classes",
# "target/classes", and "target/dependency" into classpath. This can be disable by
# setting RUN_JAVA_NO_PARSE=1.
#
# If the "Default parameters" section bellow doesn't match to user's env, then user
# may override these variables in their terminal session or preset them in shell's
# profile startup script. The values of all path should be in cygwin/unix path,
# and this script will auto convert them into Windows path where is needed.
#
# User may customize the Java classpath by setting RUN_JAVA_CP, which will prefix to existing
# classpath, or use the "-cp" option, which will postfix to existing classpath.
#
# Usage:
# run-java [java_opts] <java_main_class> [-cp /more/classpath] [-Dsysprop=value]
#
# Example:
# run-java example.Hello
# run-java example.Hello -Dname=World
# run-java org.junit.runner.JUnitCore example.HelloTest -cp "C:\apps\lib\junit4.8.2\*"
#
# Created by: Zemian Deng 03/09/2012
 
# This run script dir (resolve to absolute path)
SCRIPT_DIR=$(cd $(dirname $0) && pwd) # This dir is where this script live.
APP_DIR=$(cd $SCRIPT_DIR/.. && pwd)  # Assume the application dir is one level up from script dir.
 
# Default parameters
JAVA_HOME=${JAVA_HOME:=/apps/jdk}  # This is the home directory of Java development kit.
RUN_JAVA_CP=${RUN_JAVA_CP:=$CLASSPATH}  # A classpath prefix before -classpath option, default to $CLASSPATH
RUN_JAVA_OPTS=${RUN_JAVA_OPTS:=}   # Java options (-Xmx512m -XX:MaxPermSize=128m etc)
RUN_JAVA_DEBUG=${RUN_JAVA_DEBUG:=}   # If not empty, print the full java command line before executing it.
RUN_JAVA_NO_PARSE=${RUN_JAVA_NO_PARSE:=} # If not empty, skip the auto parsing of -D and -cp options from script arguments.
RUN_JAVA_NO_AUTOCP=${RUN_JAVA_NO_AUTOCP:=} # If not empty, do not auto setup Java classpath
RUN_JAVA_DRY=${RUN_JAVA_DRY:=}    # If not empty, do not exec Java command, but just print
 
# OS specific support. $var _must_ be set to either true or false.
CYGWIN=false;
case "`uname`" in
 CYGWIN*) CYGWIN=true ;;
esac
 
# Define where is the java executable is
JAVA_CMD=java
if [ -d "$JAVA_HOME" ]; then
  JAVA_CMD="$JAVA_HOME/bin/java"
fi
 
# Auto setup applciation's Java Classpath (only if they exists)
if [ -z "$RUN_JAVA_NO_AUTOCP" ]; then
  if $CYGWIN; then
    # Provide Windows directory conversion
    JAVA_HOME_WIN=$(cygpath -aw "$JAVA_HOME")
    APP_DIR_WIN=$(cygpath -aw "$APP_DIR")
 
    if [ -d "$APP_DIR_WIN\config" ]; then RUN_JAVA_CP="$RUN_JAVA_CP;$APP_DIR_WIN\config" ; fi
    if [ -d "$APP_DIR_WIN\target\test-classes" ]; then RUN_JAVA_CP="$RUN_JAVA_CP;$APP_DIR_WIN\target\test-classes" ; fi
    if [ -d "$APP_DIR_WIN\target\classes" ]; then RUN_JAVA_CP="$RUN_JAVA_CP;$APP_DIR_WIN\target\classes" ; fi
    if [ -d "$APP_DIR_WIN\target\dependency" ]; then RUN_JAVA_CP="$RUN_JAVA_CP;$APP_DIR_WIN\target\dependency\*" ; fi
    if [ -d "$APP_DIR_WIN\lib" ]; then RUN_JAVA_CP="$RUN_JAVA_CP;$APP_DIR_WIN\lib\*" ; fi
  else
    if [ -d "$APP_DIR/config" ]; then RUN_JAVA_CP="$RUN_JAVA_CP:$APP_DIR/config" ; fi
    if [ -d "$APP_DIR/target/test-classes" ]; then RUN_JAVA_CP="$RUN_JAVA_CP:$APP_DIR/target/test-classes" ; fi
    if [ -d "$APP_DIR/target/classes" ]; then RUN_JAVA_CP="$RUN_JAVA_CP:$APP_DIR/target/classes" ; fi
    if [ -d "$APP_DIR/target/dependency" ]; then RUN_JAVA_CP="$RUN_JAVA_CP:$APP_DIR/target/dependency/*" ; fi
    if [ -d "$APP_DIR/lib" ]; then RUN_JAVA_CP="$RUN_JAVA_CP:$APP_DIR/lib/*" ; fi
  fi
fi
 
# Parse addition "-cp" and "-D" after the Java main class from script arguments
# This is done for convenient sake so users do not have to export RUN_JAVA_CP and RUN_JAVA_OPTS
# saparately, but now they can pass into end of this run-java script instead.
# This can be disable by setting RUN_JAVA_NO_PARSE=1.
if [ -z "$RUN_JAVA_NO_PARSE" ]; then 
  # Prepare variables for parsing
  FOUND_CP=
  declare -a NEW_ARGS
  IDX=0
   
  # Parse all arguments and look for "-cp" and "-D"
  for ARG in "$@"; do
    if [[ -n $FOUND_CP ]]; then 
      if [ "$OS" = "Windows_NT" ]; then
        # Can't use cygpath here, because cygpath will auto expand "*", which we do not
        # want. User will just have to use OS path when specifying "-cp" option.  
        #ARG=$(cygpath -w -a $ARG)
        RUN_JAVA_CP="$RUN_JAVA_CP;$ARG"
      else
        RUN_JAVA_CP="$RUN_JAVA_CP:$ARG"
      fi
      FOUND_CP=
    else
      case $ARG in
      '-cp')
        FOUND_CP=1
        ;;
      '-D'*)
        RUN_JAVA_OPTS="$RUN_JAVA_OPTS $ARG"
        ;;
      *)
        NEW_ARGS[$IDX]="$ARG"
        let IDX=$IDX+1
        ;;
      esac
    fi
  done
     
  # Display full Java command.
  if [ -n "$RUN_JAVA_DEBUG" ] || [ -n "$RUN_JAVA_DRY" ]; then
    echo "$JAVA_CMD" $RUN_JAVA_OPTS -cp "$RUN_JAVA_CP" "${NEW_ARGS[@]}"
  fi
   
  # Run Java Main class using parsed variables
  if [ -z "$RUN_JAVA_DRY" ]; then
    "$JAVA_CMD" $RUN_JAVA_OPTS -cp "$RUN_JAVA_CP" "${NEW_ARGS[@]}"
  fi
else
  # Display full Java command.
  if [ -n "$RUN_JAVA_DEBUG" ] || [ -n "$RUN_JAVA_DRY" ]; then
    echo "$JAVA_CMD" $RUN_JAVA_OPTS -cp "$RUN_JAVA_CP" "$@"
  fi
   
  # Run Java Main class
  if [ -z "$RUN_JAVA_DRY" ]; then
    "$JAVA_CMD" $RUN_JAVA_OPTS -cp "$RUN_JAVA_CP" "$@"
  fi
fi

좋은 웹페이지 즐겨찾기