Sonar를 통해 안드로이드 앱 소스코드의 품질을 분석하고자 하는 분을 위해 현재 제가 사용중인 Ant 빌드스크립트를 공유합니다.


처음에는 custom_rules.xml 파일에 소스분석 스크립트를 작성했었는데요, 별도의 스크립트(analysis.xml)로 분리시켰습니다. 앱 프로젝트 루트경로에 build.xml, local.properties, project.properties 파일 등과 함께 두시면 됩니다.


[analysis.xml]

<project name="my-android-app-analysis" default="sonar">

  <property file="local.properties" />

  <property file="ant.properties" />

  <loadproperties srcFile="project.properties" />

  <fail message="sdk.dir is missing... "  unless="sdk.dir" />

  <import file="${sdk.dir}/tools/ant/build.xml" />


  <taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml">

    <classpath path="${ant.home}/lib/sonar-ant-task-2.0.jar" />

  </taskdef>


  <target name="sonar"

          depends="-set-release-mode, -release-obfuscation-check, -compile"

          description="Sonar를 이용한 소스분석">

    <xpath input="${manifest.abs.file}"

           expression="/manifest/@android:versionName"

           output="app.version.name"

           default="1.0" />


    <property name="sonar.host.url" value="http://127.0.0.1:8888/sonar" />

    <property name="sonar.jdbc.url"

                    value="jdbc:h2:tcp://127.0.0.1:9092/sonar" />

    <property name="sonar.jdbc.username" value="sonar" />

    <property name="sonar.jdbc.password" value="sonar" />

    <property name="sonar.projectKey" value="${project.app.package}:my-android" />

    <property name="sonar.projectName" value="my-android" />

    <property name="sonar.projectVersion" value="${app.version.name}" />

    <property name="sonar.java.source" value="${java.source}" />

    <property name="sonar.java.target" value="${java.target}" />

    <property name="sonar.sourceEncoding" value="UTF-8" />

    <property name="sonar.language" value="java" />

    <!-- property name="sonar.sources" value="${source.absolute.dir},${gen.absolute.dir}" / -->

    <property name="sonar.sources" value="${source.absolute.dir}" />

    <property name="sonar.binaries" value="${out.classes.absolute.dir}" />

    <property name="sonar.libraries" value="${project.target.android.jar},${jar.libs.dir}/*.jar" />

    <property name="sonar.scm.url" value="scm:svn:svn://vcs.xxx.com/trunk/my-android" />


    <!-- 더많은 소나 파라미터 : http://docs.codehaus.org/display/SONAR/Analysis+Parameters -->


    <sonar:sonar xmlns:sonar="antlib:org.sonar.ant" />


  </target>



굵은 글씨로 나와있듯이 -set-release-mode, -release-obfuscation-check, -compile 이렇게 3개의 타겟이 미리 실행되도록 해야 문제없이 소스분석이 이루어집니다. 


이렇게 만드시고 실제 수행은 Jenkins 같은 CI서버에서 수행하시면 지속적으로 소스코드 품질을 체크하실 수 있습니다. 저는 Jenkins 서버에 앱 소스분석용 Job을 만들고 아래와 같이 analysis.xml 빌드스크립트의 sonar 타겟을 실행하게 했습니다.(보통 며칠~몇주에 한번씩 수행하도록 설정)




그러면 아래와 같이 sonar 대시보드 페이지에서 내 앱 소스의 품질지표를 확인할 수 있어서 참 좋습니다.

(부끄럽게도 junit 등의 단위테스트 케이스는 없어서 테스트 커버리지는 0 퍼센트네요 -.-)



Posted by 에코지오
,

안드로이드에서 AspectJ를 사용하기 위해 이클립스 및 Ant빌드 환경을 구성하는 방법을 설명합니다.


1. AspectJ 설치

AspectJ 홈페이지(http://www.eclipse.org/aspectj/)에서 AspectJ 컴파일러를 다운로드 받아 설치합니다.

저는 개발버전인 AspectJ 1.7을 받아서 D:/Compiler/aspectj1.7 경로에 설치했습니다.

설치는 다운받은 jar 파일을 실행하면 됩니다. 


> java -jar aspectj-1.7.0.M1.jar


2. 이클립스 AJDT 플러그인 설치

이클립스 AspectJ 개발 플러그인인 AJDT를 설치합니다. http://www.eclipse.org/ajdt/downloads/ 

(이클립스 메뉴에서 Help > Install New Software... 를 선택한 후 설치 주소에 업데이트 주소 입력)

저는 개발버전인 AJDT 2.2.x를 설치했습니다. http://download.eclipse.org/tools/ajdt/37/dev/update


3. 클래스패스에 aspectrt.jar 파일 추가

aspectrt-1.7.jar 파일을 안드로이드 프로젝트의 libs 폴더에 넣어줍니다. ADT(저의 경우는 r17을 쓰고 있습니다)가 libs 폴더의 모든 jar 파일들을 자동으로 'Android Dependencies' 라이브러리에 추가해줍니다.


4. 프로젝트에 AspectJ 특성 추가

프로젝트 오른 클릭 >  Configures > Convert to AspectJ Project 를 선택하여 AspectJ 특성을 추가합니다. 그러면 프로젝트 빌더에 AspectJ Builder가 추가되고 Java Builder는 제거되며, 빌드패스에 'AspectJ Runtime Library'가 자동으로 추가됩니다.

그러나 Java Builder가 제거되면 이클립스 Problems 뷰 및 Tasks 뷰에 기존에 보였던 컴파일 에러라든가 TODO 목록이 안보이게 되므로 .project 파일에   아래와 같이 다시 Java Builder를 강제로 추가해줍니다.


  <buildSpec>

    <buildCommand>

      <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>org.eclipse.wst.common.project.facet.core.builder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>org.eclipse.jdt.core.javabuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>org.eclipse.ajdt.core.ajbuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>com.android.ide.eclipse.adt.ApkBuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

  </buildSpec>


그리고  'AspectJ Runtime Library' 라이브러리 변수는 제거해줍니다.


5. aspect 작성

예를들어 src/my/app/aop/MyFirstAspect.aj 파일을 만들고 포인트컷과 어드바이스 등을 코딩해줍니다.


AspectJ 코딩 방법은 다음사이트를 참고합니다.


http://dev.anyframejava.org/anyframe/doc/core/3.2.1/corefw/guide/aop-based-aspectj.html

http://blog.daum.net/oraclejava/15858189



개발시점에서 aspect 소스 컴파일은 AJDT로 충분하지만 릴리스용 빌드생성 또는 자동빌드를 위해서는 Ant 빌드(build.xml)을 이용하는 것이 편리합니다. (이하 Android SDK r17 버전 기준 설명입니다)


AspectJ 사용을 위한 Ant 빌드 설정

(1) local.properties 파일에 아래내용을 추가합니다.


# AspectJ 컴파일러 홈

aspectj.home=D:\\Compiler\\aspectj1.7


(2) project.properties 파일에 아래내용을 추가합니다.


# AspectJ 소스 리스트 파일 경로

aspectj.src.list=aspect-list.txt


(3) custom_rules.xml 파일을 아래의 내용으로 새로 작성합니다.(기존에 파일이 존재한다면 내용을 추가)


<?xml version="1.0" encoding="UTF-8"?>

<project name="custom_rules" default="-post-compile">


  <!-- AspectJ 컴파일 추가 -->

  <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">

   <classpath>

     <pathelement location="${aspectj.home}/lib/aspectjtools.jar" />

   </classpath>

  </taskdef>

  <!-- iajc 타스크 설명 : http://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html -->

  <!-- sourceRoots, inpath, aspectpath에 대한 설명 : http://www.jroller.com/tmjee/entry/iajc_usage -->

  <target name="-post-compile">

    <echo message="Weaving aspects to .class files before dex converts .class files to .dex file" />

   <!-- aspectpathref : 라이브러리에 속한 애스펙트도 적용할 경우 설정 -->

    <iajc destDir="${out.classes.absolute.dir}"

          bootclasspathref="android.target.classpath"

          classpathref="project.libraries.jars"

          classpath="${aspectj.home}/lib/aspectjrt.jar"

          sourceroots="${source.absolute.dir}"

          inpath="${out.classes.absolute.dir}"

          aspectpathref="project.libraries.jars"

          Xlintwarnings="true"

          showWeaveInfo="true"

          encoding="${java.encoding}"

          source="${java.source}"

          target="${java.target}">

    </iajc>

  </target>


</project>


만약 프로젝트 유형이 안드로이드 '라이브러리' 프로젝트라면 아래와 같이 -post-compile 타겟을 정의합니다.


    <echo message="Weaving aspects to .class..." />

    <iajc destDir="${out.classes.absolute.dir}"

          bootclasspathref="android.target.classpath"

          classpathref="project.libraries.jars"

          classpath="${aspectj.home}/lib/aspectjrt.jar"

          Xlintwarnings="true"

          showWeaveInfo="true"

          encoding="${java.encoding}"

          source="${java.source}"

          target="${java.target}">


      <sourceroots>

        <pathelement location="${source.absolute.dir}" />

        <pathelement location="${gen.absolute.dir}" />

      </sourceroots>


      <!--

       inpath="${out.classes.absolute.dir}"

       => 이 옵션을 적용하면 앱에서 라이브러리의 애스펙트도 적용하도록 

            설정한 경우 bad WeaverState.Kind: -115 에러 발생함

      -->

    </iajc>


    <!-- 라이브러리 프로젝트인 경우 -compile 타겟에서 생성된 classes.jar를 위빙된 클래스로 교체 -->

    <if condition="${project.is.library}">

      <then>

        <echo>Overwrite library output jar file with weaved classes...</echo>

        <jar destfile="${out.library.jar.file}" update="false">

          <fileset dir="${out.classes.absolute.dir}"

                   includes="**/*.class"

                   excludes="${manifest.package.path}/R.class ${manifest.package.path}/R$*.class ${manifest.package.path}/Manifest.class ${manifest.package.path}/Manifest$*.class ${manifest.package.path}/BuildConfig.class" />

          <fileset dir="${source.absolute.dir}"

                   excludes="**/*.java ${android.package.excludes}" />

        </jar>

      </then>

    </if>




(4) proguard-project.txt에 다음 내용을 추가합니다.


# aspect 클래스 및 aspect가 적용되는 클래스에서 AspectJ 라이브러리를 참조할 수 없다는 경고 제거

# (can't find referenced class)

-dontwarn org.aspectj.**


# 패키지 변경 금지(주석해제시 런타임에 java.lang.NoSuchMethodError 에러 발생)

#-repackageclasses ''

#-allowaccessmodification


# AspectJ 클래스 보존

-keep class org.aspectj.**


# Aspect 클래스 및 멤버 보존

-keep @org.aspectj.lang.annotation.Aspect class * { *; }

-keepclasseswithmembers class * {

    public static *** aspectOf();

}


# around 어드바이스가 적용되는 target 클래스에서 around 어드바이스 메소드를

# 참조할 수 없다는 경고 제거(can't find referenced method) : aspect 클래스를 지정

-dontwarn my.app.aop.**

(또는 -dontwarn my.app.**.*Aspect 식으로 설정)


(5) aspect 소스 리스트 파일 작성

aspectj.src.list 속성으로 정의한 aspect-list.txt 파일을 생성하고, aspect 소스 리스트를 한줄에 하나씩 나열합니다.

경로는 프로젝트 루트에 대한 상대경로입니다.


src/my/app/aop/MyFirstAspect.aj

src/my/app/aop/MySecondAspect.aj

...


Posted by 에코지오
,
안드로이드에서 Ant build.xml 스크립트를 통해 앱을 빌드하는 경우에 ant release 명령어를 실행하면 기본적으로는 서명 안된 앱이 만들어집니다. 서명된 앱을 만들려면 build.properties에 아래처럼 키 파일 위치를 지정해주면 되죠.

key.store=path/to/mykeystore.jks
key.alias=mykeystorealias


그러나 문제는 이렇게 설정하고 ant release를 다시 실행하면 키스토어 비밀번호를 묻는 프롬프트가 뜨면서 우리에게 입력을 요구한다는 겁니다.

... ....
-package-release:
[apkbuilder] Creating MyApp-unsigned.apk for release...

-release-prompt-for-password:
    [input] Please enter keystore password (store:mykeystore.jks):
mykeystorepass (입력값)
    [input] Please enter password for alias 'mykeystorealias':
mykeystorealiaspass (입력값)
... ....


어쩌다가 빌드한다면 별 문제 아니지만 수시로 소스 수정해서 빌드해야하는 경우라면 무지 귀찮은 일입니다. 한마디로 완전한 자동화가 아닌겁니다.
버뜨, 방법이 있습니다. build.properties에 아래 프로퍼티를 추가해주면 비밀번호 프롬프트 없이 release모드로 서명된 apk가 만들어집니다.

key.store.password=mykeystorepass
key.alias.password=mykeystorealiaspass


보안이 염려스럽다면 ant 실행옵션에 추가해주셔도 됩니다.

ant -Dkey.store.password=mykeystorepass  -Dkey.alias.password=mykeystorealiaspass release


Posted by 에코지오
,
WAS를 start/stop/restart하거나 웹어플리케이션을 deploy/undeploy/redeploy하는 작업을 자동으로 처리하기 위해 쓸 수 있는 방법은 어떤게 있을까?

1. 스크립트 실행
작업을 정의한 스크립트를 실행한다. 아마 이게 제일 속편한 방법일지도 모른다.
Ant에서는 telnet, exec, sshexec 등의 타스크를 이용하여 실행하면 된다.

Ant sshexec 타스크를 통해서 원격지의 Tomcat을 start하는 예제

<target name="remote-tomcat-start">
  <sshexec host="${ssh.hostname}"
  port="${ssh.port}"
  username="${ssh.username}"
  passphrase=""
  trust="true"
  keyfile="${ssh.key.file}"
  command="${tomcat.home}/bin/startup" />
  <sleep seconds="${sleep.time}" />
</target>


2. WAS에서 제공하는 Ant 타스크 또는 Maven 플러그인 이용
대부분의 WAS가 어드민화면을 통하지 않고 여러가지 작업을 수행할 수 있는 수단을 제공한다.

Tomcat에서 제공하는 deploy 타스크를 이용하여 war를 deploy하는 Ant 예제

    <target name="install" description="Install application in Tomcat"
        depends="package-web">
        <deploy url="${tomcat.manager.url}"
            username="${tomcat.username}"
            password="${tomcat.password}"
            path="/${webapp.name}"
            war="file:${webapp.dist}/${webapp.war}"/>
    </target>


3. Cargo 이용
Cargo는 WAS 마다 다른 형태의 API를 래핑하여 표준적인 방법으로 WAS를 핸들링할 수 있게 해준다. 그러나 아직 지원하는 WAS가 많지 않다.

Ant에서 cargo 타스트를 이용하여 Tomcat을 start하는 예제

  <cargo containerId="tomcat5x" home="${tomcat.home}" output="${tomcatlog.dir}/output.log"
      log="${tomcatlog.dir}/cargo.log" action="start">
    <configuration home="${tomcatconfig.dir}">
      <property name="cargo.servlet.port" value="8080"/>
      <property name="cargo.logging" value="high"/>
      <deployable type="war" file="${mywarfile}"/>
    </configuration>
  </cargo>
Posted by 에코지오
,
Ant는 세밀하게 빌드를 설정하기 좋지만 미리 정해진 규칙이나 프로세스가 없기 때문에 알파부터 오메가까지 모든걸 내가 다 정의해야한다. Ant는 나에게 거의 모든 자유를 주며, 복잡한 빌드환경에서도 적절히 대처할 수 있는 온갖 task를 제공해준다. 그러나 자유에는 책임이 따르듯이 규칙과 절차를 만드는 몫은 나에게 있다. 이렇게 수립된 규칙과 절차는 프로젝트마다 제각각이어서 대부분 호환되지 않는다.

Maven은 Ant에 비해 자유도는 낮지만 규칙을 잘 따른다면 작업을 쉽게 처리할 수 있다. 널리 통용되는 빌드 프로세스(phase)와 수행할 작업이 내장되어 있어서 설정을 최소화해주며, 의존관계의 라이브러리를 체계적으로 다루는 능력이 뛰어나다.(원래 ant는 의존성 관리를 하지 않으나 ivy를 이용하면 ant에서도 충분히 maven처럼 의존성 관리를 할 수 있다고 함) 그러나 Ant만큼 풍부하고 작은 단위의 task는 제공하지 않고 대신, plugin이라는 다소 큰 덩어리의 도구를 제공한다. 딱딱한 빌드절차, 묵직한 plugin 등 커스터마이징이 극히 제한적이어서 국내 SI프로젝트처럼 국제적인 상식(?)을 잘 따르지 않는 복잡한 빌드환경에서는 적합하지 않을 수 있다.

그럼 Ant의 높은 자유도와 Maven의 다듬어진 프로세스를 두루 갖는 그런 빌드 도구는 없는가?
최근 Ant와 Maven을 뛰어넘기 위해 스크립트 언어 기반으로 빌드를 설정하려는 시도가 많아지고 있다.

찾아보면 BuildrGradle, Raven 대충 이정도 나온다.

Raven과 Buildr은 ruby 언어로, Gradle은 groovy 언어로 빌드를 작성한다.
Raven은 Ant 스타일과 비슷하고 Buildr과 Gradle은 Maven의 사상이 들어있다.

자 이쯤에서 하나 골라잡아 공부해야 하는건가?
Posted by 에코지오
,

우리가 개발하는 어플리케이션은 최종 사용자에게 서비스되기 전에 여러 장소를 거칩니다.

개발자 로컬PC -> (소스저장소) -> 빌드서버(CI서버) -> 개발서버 -> 테스트서버 -> 스테이징서버 -> 운영서버

불행히도 이렇게 거쳐가는 서버에 따라서 환경/정책이 조금씩 다르기 때문에 우리는 개발소스에 포함된 설정값을 다르게 가져가야 합니다. 예전에는 소스가 서버 사이를 옮겨갈 때마다 수작업으로(vi 에디터로) 설정값을 매번 편집을 해주거나, 설정값을 포함한 파일을 빼고(!) 소스를 옮기기도 했습니다. 여러분은 어떤 방법으로 설정값을 다르게 세팅하셨습나요?

여기, 좀더 우아한 방법이 있습니다.

아, 그보다 먼저 설정값을 포함하는 파일을 보통 뭐라고 부르나요? 설정파일 ? 리소스 파일?  뭐라고 부르든 리소스는 주로 xml, properties 로 작성을 하죠. 레일스에서는 yml인가 이런것도 있더군요. 암튼.

그리고 로컬,개발,운영 등 서버의 환경차이에 따라 리소스 파일을 변환하여 개발소스에 포함된 설정을 달리하는 일을 뭐라고 부르나요? 환경맞춤작업? 리소스변환리소스 설정치환? 이런 거에 대한 공식적인 용어를 들은 바가 없어서 일단은 제목에 리소스 설정치환이라고 임의대로 용어를 지었습니다. 혹시 널리 사용되는 용어를 아시는 분은 알려주세요. 언뜻 profile, portable이란 단어가 떠오르기는 합니다만....

아래는 제가 알고 있는 리소스 설정치환 방법 2가지입니다.(리소스 필터링, 리소스 교체 역시 모두 제가 임의로 만든 용어입니다. 더 나은 용어가 있으면 알려주세요.)

1. 리소스 필터링(filtering)
-빌드시에 설정 파일의 내용을 수정하는 방법
-설정값을 하드코딩하지 않고 정해진 형식의 변수로써 설정. 예를 들어 ${jdbc.password}.
-빌드 실행시 설정 파일 내의 변수는 환경에 적합한 설정값으로 치환됨
-환경별 설정값은 빌드스크립트에 보관됨(메이븐의 경우 프로파일 엘리먼트에)

2. 리소스 교체(replacing)
-빌드시에 기준(로컬) 설정 파일을 다른 파일로 교체하는 방법
-설정 파일을 환경별로 분리하여 관리
  (1)환경별로 별도 디렉토리를 만들어 기준 파일과 동일한 파일명으로 관리.
      예를 들어 /web/WEB-INF/web.xml 이 로컬PC용 설정파일이면,
      개발서버용 web.xml은 /conf/dev/web.xml에 두고 관리.
  (2)기준 설정파일과 동일한 경로에, 다른 파일명으로 관리.
      예를 들어 개발서버용 web.xml을 /web/WEB-INF/web.xml.dev 라는 이름으로 관리.
-빌드실행시 환경에 맞는 파일을 골라서 (1)빌드디렉토리로 이동하거나 (2)파일명을 변경하여 기준 설정 파일을 덮어씀

1번 리소스 필터링의 경우 메이븐에서는 Profile 기능과 Resource Filtering 기능을 이용하면 되고, 2번 리소스 교체의 경우 메이븐에서는 Profile 기능과 Ant의 copy 타스크 조합으로 처리할 수 있습니다. 아래는 메이븐에서 2번을 처리한 예제입니다.

... ...
<plugin>
 <artifactId>maven-antrun-plugin</artifactId>
 <executions>
  <execution>
   <id>resource-changing</id>
   <phase>process-resources</phase>
   <goals><goal>run</goal></goals>
   <configuration> <tasks>
          <copy todir="${project.build.outputDirectory}"
                    overwrite="true" preservelastmodified="true" verbose="true">
               <fileset dir="${project.build.outputDirectory}"
                          includes="**/${conf.replace.pattern}" />
                   <mapper type="glob" from="${conf.replace.pattern}" to="*" />
          </copy>
    </tasks></configuration>
  </execution>
...... .......
..... ........
 <profiles>
  <profile>
   <id>env-dev</id>
   <activation>
    <property><name>env</name><value>dev</value></property>
   </activation>
   <properties>
    <conf.replace.pattern>*.dev</conf.replace.pattern>
   </properties>
  </profile>
  <profile>
   <id>env-prod</id>
   <activation>
    <property><name>env</name><value>prod</value></property>
   </activation>
   <properties>
    <conf.replace.pattern>*.prod</conf.replace.pattern>
   </properties>
  </profile>
 </profiles>
Posted by 에코지오
,
Ant 에서 원격서버의 명령을 실행할 때 그 명령이 백그라운드로 계속 돌아가는 프로세스를 생성한다면 약간 골치아픈 일이 벌어진다.  대표적인게 WAS시작 스크립트를 원격으로 실행하는 건데, WAS를 띄우면 WAS는 계속해서 console에 정보를 출력하고 이는 WAS가 죽기 전에는 끝나지 않는다.
 
       <sshexec host="${wasserver.ip}" username="${wasserver.username}"
         password="${wasserver.password}" trust="true"  command="start.sh" />

아무 생각없이 이렇게 타스크를 정의했다간 서버단의 콘솔메시지가 로컬의 ant를 실행시킨 커맨드 창에 주루룩 나오면서 ant 실행이 끝나지 않을 것이다. (이게 WAS 시작 스크립트에서 흔히 볼 수 있는 nohup과 관련된 것인지는 잘 모르겠다)

그래서 sshexec 옵션에 timeout="2초" failonerror="false"을 추가하면 timeout 후 빌드가 실패한다.(maven으로 돌렸는데 메이븐이 그 이후의 단계를 더이상 진행하지 않고 그냥 끝나버렸다)

안타까워하다가 혹시나하고 의존라이브러리인 ant-jsch와 jsch 버전을 업그레이드했더니 다행히 timeout후 빌드결과가 성공으로 나온다.

    <dependencies>
     <dependency>
      <groupId>org.apache.ant</groupId>
      <artifactId>ant-jsch</artifactId>
      <version>1.7.1</version>
     </dependency>
     <dependency>
      <groupId>com.jcraft</groupId>
      <artifactId>jsch</artifactId>
      <version>0.1.38</version>
     </dependency>
    </dependencies>

WAS에서 제공하는 ant 타스크를 이용하면 깔끔하지 않겠냐하는 분도 계시겠지만 보통 WAS 시작,종료 스크립트에 벤더들이 여러가지로 장난?을 많이 쳐놓아서 그것도 쉽지만은 않다.

Posted by 에코지오
,

weblogic 10 환경에서 ant를 통해 웹어플리케이션을 redeploy하기 위해 삽질을 했으나 결국 실패했다.

1. 먼저 cargo를 써보려했으나 cargo는 아직 weblogic10을 지원하지 않는다.

2.ant 에서 아래처럼 작성하고 실행하니 아무런 일도 일어나지 않는다.
(클래스패스에 weblogic/server/lib/*.jar는 걸린상태)

 <taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy"/>
 <target name="redeploy">
  <wldeploy action="redeploy" verbose="true" name="MyWebApp"
                   user="weblogic" password="weblogic"
                   adminurl="t3://127.0.0.1:7001" targets="AdminServer" />
 </target>

3. 커맨드 창에서 직접 명령을 실행하니 weblogic.utils.Debug 클래스가 없다는 에러가 난다.

java -cp weblogic.jar weblogic.Deployer -adminurl http://127.0.0.1:7001 -username weblogic -password weblogic redeploy -name MyWebApp

wls-api.jar를 클래스패스에 추가하고 실행하니 이번엔 weblogic/rmi/extensions/RemoteRuntimeException 클래스가 없다는 에러가 난다. 슬슬 짜증이 난다.

4. 웹로직 문서에 나온대로 weblogic/server/bin/setWLSEnv.cmd를 먼저 실행 후 3번을 다시 시도해보니 성공!

정녕 순수 ant로 redeploy하는 방법은 없는 것인가? 혹시 weblogic에 내장된 ant를 써야하는 건가?
아니면 내가 뭐 빠뜨렸나...?

Posted by 에코지오
,