반응형
반응형

어플리케이션을 하나 출시하기 위해서, 세팅되는 작업환경은 보통 아래와 같을 것이다.

Local, Dev, QA, Live

 

보통 DB정보와, Server to Server를 이용하는 API의 URL은 각 환경마다 다를 가능성이 매우 크다.

하지만, 매번 배포할때마다 이것을 수정하는 것은 매우 귀찮은 일이고, 비효율적이다.

(물론 이렇게 쓰는사람이 있을까 싶긴 하다;;)

 

Maven의 Profile 관리 기능과 War Plugin을 이용하면, 매우 편리하게 설정파일 등을 폴더에 넣어두고

각 환경에 맞게 -P 옵션만으로, 원하는 환경이 세팅되게 하는 것이 가능하다.

 

[pom.xml]


<profiles>
     <profile>
          <id>dev</id>
          <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <configuration>
                            <containerConfigXML>src/main/webapp/META-INF/dev/context.xml</containerConfigXML>
                            <webResources>
                                <resource>
                                    <directory>src/main/webapp/META-INF/dev</directory>       <!-- 현재 프로젝트의 폴더 위치 -->
                                    <filtering>true</filtering>     <!-- 여기서는 그냥 true인데, 특정 파일만을 필터링 하는 기능도 지원 -->
                                    <targetPath>META-INF</targetPath>     <!-- 배포가 된 후 폴더의 위치  -->
                                </resource>
                            </webResources>
                        </configuration>
                    </plugin>
                </plugins>
            </build> 
     </profile>
     ... 
</profiles> 

 

대충 위와 같이 context설정은 가능하고, properties나 logging관련 파일들도 resource element를 만들어서 참조하게 하면,

-P 만으로 각 환경에 맞게 리소스가 컨트롤이 가능함.

 

작년에 했던 것들인데 이제서야 정리... 

반응형
,
반응형

클라든 서버든 어플리케이션 버전의 경우 0.0.1 등으로 표시를 한다.

 

이럴 경우 DB에서는 >, < 등 범위 연산을 어느 정도 지원을 하지만, Java단에서는 "." 단위로 Split를 해서 각각 비교를 해야 되는 번거로움이 존재하는데, 이를 편리하게 해주는 라이브러리가 있었다.

 

1. 의존성 추가 


<dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-artifact</artifactId>
            <version>3.2.3</version>
</dependency>

 

 

2. 확인 


@Test
public void test_stringCompareVersion() {
        DefaultArtifactVersion currentVersion = new DefaultArtifactVersion("0.0.27");
        DefaultArtifactVersion preVersion = new DefaultArtifactVersion("0.0.1");
        DefaultArtifactVersion nextVersion = new DefaultArtifactVersion("0.0.84");
        DefaultArtifactVersion sameVersion = new DefaultArtifactVersion("0.0.27");
        
        System.out.println(currentVersion.compareTo(preVersion));    // 앞에 버전보다 뒤에 버전이 작은 경우 1
        System.out.println(currentVersion.compareTo(nextVersion));    // 앞에 버전보다 뒤에 버전이 큰 경우 -1
        System.out.println(currentVersion.compareTo(sameVersion));    // 같으면 0
}

 

메이븐에서 만든것이니 내가 만드는거 보단 낫겠지;;

어느정도 믿고 사용하자. 

반응형
,
반응형

Nexus는 팀 단위 프로젝트에서 라이브러리 공유 등을 할 때 유용하게 사용할 수 있는 무료 Repository이다.

 

Maven을 사용하는 경우 Pom.xml에서 의존성을 넣으면, Maven Central Repository에서 의존성을 가져오게 되는데,

Nexus를 사용하는 경우 Nexus가 Proxy역할을 해주고 원격지 라이브러리를 로컬에 캐싱하기 때문에, 의존성을 가져오는 데 걸리는 시간도 단축될 수 있다.

3rd party library도 Nexus에 등록해두고 사용하면, 따로 라이브러리 파일을 관리해야하는 이슈가 없어진다. 

 

설치 법에 대해 알아보자.

 

1. 다운로드 및 설치 

 - http://www.sonatype.org/nexus/go/에서 파일을 다운 받은 후에 압축을 풀어준다.

 

2. 실행

 - 압축이 풀어진 폴더에 보면 bin폴더가 있는데, 그 안에 nexus를 실행해준다.

(root로 실행하는 경우에만) root권한으로 실행하는 것은 비권장한다고 하면서 팅긴다. vi 에디터 등으로 nexus파일을 직접 열어서 RUN_AS_USER부분의 주석을 풀고 root을 넣어주면 실행이 가능하다.

 

3. 확인 및 로그인

 - jetty기반으로 되어 있고, 포트는 8081이다. http://localhost:8081/nexus로 확인이 가능하다.

   아이디, 비밀번호는 초기설정이 admin / admin123이다.

 

4. 웹 UI 접근에 성공하였으면, Repositories메뉴로 들어가서 Public Repositories를 선택 후, Configuration탭으로 들어간다.

 - Available Repositories로 Central만 남기고 모두 옮겨준다. Save버튼 클릭 

 

5. 이제 상단의 Central을 선택 후, Configuration탭으로 들어간다.

 - Download Remote Indexes옵션을 True로 바꿔준다. (False인 경우 리모트에 접속해서 받아오는 데, True로 하면 인덱싱 되어 있는 목록에서 가져와서 다운로드 속도가 빨라진다고 한다.) Save버튼 클릭 

 

6. 4, 5의 설정을 마치면, Nexus가 동기화 작업을 수행한다.  

 - 매우 오래걸리는 작업이며, 작업 진행 상황 확인은 좌측 메뉴의 Administration/Scheduled Tasks에서 확인이 가능

(개발 머신이 드럽게 느려서, 13분이나 걸림 ㅋㅋㅋㅋ;; 센트럴에 있는거를 전부 땡겨오는듯)

 

7. pom.xml에 repositories 명시해두고 쓰면 된다.


<repositories>
 <repository>
  <id>mycompany.internal.repo</id>
  <url>http://host/nexus/content/repositories/releases/</url>
  <releases>
   <enabled>true</enabled>
  </releases>
 </repository>
</repositories>

 

공통 모듈 같은 경우 별도의 프로젝트로 떼어내서, 해당 소스만 배포하고, 나머지 프로젝트에서 import하여 사용하면, 편리하게 사용이 가능한 것 같음.

3rd party library를 등록해서 사용하면 꽤 유용할 것 같다.

 

우리 프로젝트에서 제대로 사용하려면, 공통 모듈 분리에 대해서 고민해봐야 할 것 같다.   

반응형
,
반응형

Nexus에 Repository를 하나 생성한다.

 

ID, Name은 대충 적어줘도 되지만, Repository Policy에서 정책을 자신이 원하는것과 다른걸로 지정해주면

Deploy시 실패하게 되므로 주의하자.

 

Repository가 생성되었으면, 해당하는 url을 우리가 공유해야 할 프로젝트의 pom.xml에 넣어준다. (보통 공통모듈 프로젝트)

아래와 같이..  

 


<distributionManagement>
        <repository>
            <id>CommonModule</id>
            <name>CommonModule</name>
            <url>http://localhost:8081/nexus/content/repositories/commonModule</url>
        </repository>
</distributionManagement>

 

당연히, Nexus에 만들어둔 repository와 id, name, url이 일치해야 한다.

 

그리고 상단에 groupId, artifactId, version이 다른 사람이 의존성을 주입해서 사용할 때,

넣는 이름이 되므로, 신중하게 결정하자.

version의 경우 위에서 설명한 Repository Policy에 해당하는 단어가 포함되어 있어야 한다.

(RELEASE로 했을 경우 0.0.1-RELEASE와 같이 해준다. 정책이 RELEASE인데 SNAPSHOT이 포함되어 있으면, Deploy시에 repository정책이 일치하지 않아서 실패한다.)

 

이렇게 해주고, mvn clean deploy를 해주면, Nexus에 내 프로젝트가 등록이 되어, 다른 팀원과 공유가 가능해진다.

하지만, 다른 팀원들이 내부 소스를 보지 못하는 이슈가 있으므로, maven-source-plugin, maven-deploy-plugin을 이용하여, 소스까지 업로드 해주는 것이 좋다.

(이건 다음 포스팅에서 작성하는 걸로..) 

 

이제 공통모듈쪽 프로젝트 작업은 끝났고, 다른 팀원들이 사용할 수 있게 해줘야 하는데,

사전 작업이 약간 필요하다.

 

1. .m2폴더의 settings.xml을 열어서, nexus repository에 대한 정보를 등록한다. (.m2폴더는 이클립스 기준으로 External 등의 설정을 하지 않았다면, 윈도우 사용자 폴더\.m2 경로에 존재한다.)

아래와 같이 추가해준다.

 

  <servers> 
    <server>
        <id>commonModule</id>      <!-- 이것도 물론 아까 nexus에 만들어둔 id와 동일해야 함. -->
        <username>admin</username>
        <password>admin123</password>
    </server>
  </servers>

 

2. 공통모듈 프로젝트의 의존성을 주입할 프로젝트의 pom.xml을 열어서 아래와 같이 추가해줌.

  

 

<repositories>
      <repository>
            <id>commonModule</id>  <!-- 동일해야함! -->
            <url>http://localhost:8081/nexus/content/repositories/commonModule</url>
        </repository> 
  </repositories>
 
  <dependencies>
      <dependency>
           <!-- 공통 모듈 프로젝트의 pom.xml 상단에 있는 정보와 동일해야함. artifactId, version도 마찬가지--> 
          <groupId>companyName</groupId>      
          <artifactId>commonModule</artifactId>
          <version>0.0.1-SNAPSHOT</version> 
      </dependency> 
  </dependencies>

참고로 이클립스를 사용하는 경우, 같은 workspace에 공통모듈 프로젝트가 포함되어 있는 경우  

의존성이 주입된 원격 Nexus에 있는 라이브러리를 참조하는 것이 아니라, 바로 그 프로젝트의 라이브러리를 참조하는 것 같다.

디버깅하기도 편하고 더 좋은듯..

 

이제 CI툴과의 연동을 진행해봐야겠다. 

반응형
,
반응형

공통 모듈 프로젝트를 분리해서, Nexus에 Deploy하는 경우

의존성이 주입된 라이브러리들과 모든 기능들을 사용은 할 수 있지만,

내부는 볼 수가 없다.

 

소스가 없기 때문인데.. 이를 해결하기 위해 Maven Source Plugin이라는 것이 있었다.

아래와 같이 하니깐, 소스까지 배포가 되더라. (퍼온거라 그냥 대충 복붙;;) 

 


<plugin>
        <artifactId>maven-source-plugin</artifactId>
        <version>2.3</version>
        <executions>
             <execution>
             <id>attach-sources</id>
             <phase>verify</phase>
             <goals>
                <goal>jar</goal>
             </goals>
             </execution>
        </executions>
</plugin>             
<plugin>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>2.8.2</version>
        <executions>
              <execution>
               <id>deploy</id>
               <phase>deploy</phase>
                </execution>
        </executions>
 </plugin>

 

이 작업으로 인해, 공통 모듈에서 뭔가 이상한 것 같다라는 말이 나오면,

소스를 직접 열어서 디버깅해보라고 할 수 있어서 귀찮음이 반감될 것 같다. 

반응형
,
반응형

매번 업데이트 하도록 업데이트 정책인 updatePolicy옵션을 always로 바꾸어준다.

이렇게하면 매번 빌드 시마다 라이브러리를 받게 된다.



 

<repositories>
        <repository>
            <id>nexus</id>
            <url>{host}</url>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>always</updatePolicy>
            </snapshots> 
        </repository>
    </repositories>
반응형
,
반응형

아무것도 설정을 건드리지 않은 상태에서 maven으로 빌드를 하면, 앞에 프로젝트명-SnapShot-0.0.1.war 이런식으로 붙게 된다.


저 파일을 was에 올리면 was도 별 다른 설정이 없으면 localhost:8080/프로젝트명-SnapShot-0.0.1 이런식으로 url이 따지게 되어,

매번 프로젝트명.war로 rename을 해서 올렸던 기억이 있다.


이 작업을 maven단에서 자동으로 해주는 옵션이 존재한다. 

아래 내용만 pom.xml에 추가해주면 프로젝트명.war로 깔끔하게 패키징이 된다.



<build>
    <finalName>프로젝트명</finalName>
</build>


귀찮아서 Shell로 만들어서 매번 Rename했었는데, 위 옵션을 추가함으로써, 뻘짓을 안하게 되었다.

반응형
,
반응형

Eclipse(STS)기준으로 설명함.


Maven 명령어나 Eclipse의 Maven Build등을 이용하여 실행되어야 할 파일을 한 번 실행해준다.

(한 번 실행이 되어야, 이후에 나올 메뉴에서 빌드 선택이 가능하다.)


프로젝트 우클릭 후, Export를 선택한다.



발생하는 팝업에서 [Java] - [Runnable JAR file] 을 선택 후 [Next]버튼 클릭

 


Launch configuration에서는 아까 Maven Build로 실행했던 것을 선택해주고, 

Export destination에는 jar파일을 어디로 뽑을지 입력한다.

나머지 설정은 Default로 유지해준다.

 


Finish를 누르면, destination 위치에 jar파일이 생성되고, java -jar 만들어진파일.jar 로 실행해도

manifest가 지정되지 않았다는 등의 메시지는 뜨지 않는다.

반응형
,
반응형

본 포스트는 JUnit에 대한 기초적인 지식이 있다는 가정하에 작성되었습니다.

 

spring test에서 지원하는 MockMVC의 경우,

테스트를 돌릴 때마다, application Context를 로딩하는 시간때문에 사전 대기 시간이 걸린다는 게 좀 아쉬웠습니다.

(그래봐야 몇 초 안되지만... 우리들은 한국인)

 

그러던 중, spring mvc구조에서 매우 쉽게 도입할 수 있는 Mockito라는 녀석을 찾게 되었습니다.

 

매뉴얼도 한국어군요.. 매우 훌륭합니다. 

https://code.google.com/p/mockito/wiki/MockitoFeaturesInKorean

 

JUnit과의 연동도 매우 훌륭합니다. (거의 할게 없을 정도..)

@RunWith(MockitoJUnitRunner.class) 이거 하나만 테스트가 작성될 클래스에 붙여주면 됩니다.

 

Mocking하는 과정도 매우 간단합니다.

만약에 LoginDao라는 객체를 Bean으로 만들어서 쓰는 구조라면..

아래와 같이 @Mock만 붙여주면 끝납니다.

※ Mocking : 예를들어 DB통신하는 객체가 있다면, DB통신 없이도 동일하게 행동하도록 다른 객체로 바꿈. 

 

@Mock  

LoginDao loginDao;

 

Mocking하려는 객체가 참조하는 다른 Bean이 있는경우..

만약에 LoginService가 LoginDao를 포함하는 구조라고 합시다.

아래와 같이 써주면, 포함된 Bean들도 모두 Mock객체로 만들어줍니다.

 

@InjectMocks

LoginService loginService;

 

여기까지 Mock객체 생성법이었구요.

 

이제 Stubbing에 대해 알아보도록 하죠.

Mock객체가 실제로 DB통신등 네트워크 통신을 하지 않고 메모리상에서만 돌아가기 때문에,  

대규모 프로젝트에서는 이게 좀 귀찮은 작업이 될 수 있습니다.

 

loginDao의 login(int a, String b)이라는 메소드가 있다고 치고, 리턴형이 int라고 가정합시다.

그리고 해당 메소드에서 무조건 10이라는 값이 나오게 하고 싶습니다.

그럴 경우, 아래와 같이 작성할 수 있습니다. 

 

when(loginDao.login(anyInt(), anyString())).thenReturn(10);

 - argument에 정확한 값을 넣어도 되지만, 보통은 어떤 값이 들어올지 모르기 때문에, 아무값이나~ 라는 anyInt(), anyString()등의 기능도 지원을 해줍니다.  

 

이후에 JUnit에서 지원하는 Assert관련 메소드등을 이용해서 값 검증을 하시고,

Mockito에서 지원하는 verify 관련 기능들을 이용하시면, 더더욱 강력한 테스트를 만들 수 있습니다.

반응형
,
반응형

자체적으로 돌아가는 클라이언트 테스트 (시나리오 테스트)를 만들기 위해,

JUnit으로 Flow를 쭉 짜놓고, 잘 돌아가는 것을 확인하였는데,

이것을 여러번 돌리고 싶었다.

 

처음에는 for(int i=0; i<count; ++i) 를 이용해서 돌렸는데..  

로직이 테스트 한개에 들어가 있는 것이니.. 

예상대로 count만큼 돌았을 때에 대한 최종 응답시간만 확인을 할 수 있었다.

 

그러던 중 JUnit에서 제공하는 기능인 Parameterized에 대해 알게 되었다.

 

적용방법은 매우 간단하다.

 

 

1. 테스트가 작성된 클래스 상단에 @RunWith(Parameterized.class)를 붙여준다.

 

2. 파라미터가 세팅될 Collection을 구현한다. 


@Parameters  
    public static Collection<Object[]> generateParams() {  
         List<Object[]> params = new ArrayList<Object[]>();  
         for(int i=0; i<TEST_BOT_COUNT; ++i) {  
              params.add(new Object[] {i});  
         }  
         return params;  
    }

 

 

3. 돌려보면, 지정한 개수만큼 JUnit Report가 발생한다.

반응형
,
반응형