Apache Common Lang의 StringUtils 메소드를 많이 활용하는 부분을 작성.




import org.apache.commons.lang3.StringUtils;

import org.junit.Assert;

import org.junit.Test;


public class StringUtilsTest {

@Test

public void test() {

Assert.assertEquals("", StringUtils.EMPTY);

Assert.assertEquals(-1, StringUtils.INDEX_NOT_FOUND);

String string = "";

Assert.assertSame(true, StringUtils.isEmpty(string));


String ironman="This is a Iron man";

Assert.assertEquals("This is...", StringUtils.abbreviate(ironman, 10));


Assert.assertEquals(" 2", StringUtils.leftPad("2", 2));

Assert.assertEquals("02", StringUtils.leftPad("2", 2, "0"));

Assert.assertEquals(true, StringUtils.isBlank(""));

Assert.assertEquals(true, StringUtils.isBlank(null));

Assert.assertEquals(true, StringUtils.isEmpty(""));

Assert.assertEquals(true, StringUtils.isEmpty(null));

Assert.assertEquals(false, StringUtils.isNotEmpty(""));

Assert.assertEquals(true, StringUtils.isNotEmpty("1111"));

String[] split = StringUtils.split("000_111_AA_222_333", "_");

Assert.assertEquals("000111AA222333", split[0]+split[1]+split[2]+split[3]+split[4]);


String test = "Test";

StringUtils.equals("Test", test);


Assert.assertEquals(2, StringUtils.countMatches("/aaa/bbb", "/"));

Assert.assertEquals("AAABBB", StringUtils.join("AAA", "BBB"));

String[] array = new String[]{ "LA", "Seattle", "SanJose"};

Assert.assertEquals("LA,Seattle,SanJose", StringUtils.join(array, ","));


Assert.assertEquals(true, StringUtils.startsWith("https://www.google.com", "https://"));

Assert.assertEquals(true, StringUtils.endsWith("https://www.google.com", ".com"));

Assert.assertEquals("st", StringUtils.left("string", 2));

Assert.assertEquals("ing", StringUtils.right("string", 3));

Assert.assertEquals("A-Z", StringUtils.upperCase("a-z"));

Assert.assertEquals("A-z", StringUtils.capitalize("a-z"));

Assert.assertEquals("a-z", StringUtils.lowerCase("A-Z"));

Assert.assertEquals(true, StringUtils.isNumeric("11"));

Assert.assertEquals(true, StringUtils.isAlphanumeric("11"));

Assert.assertEquals(true, StringUtils.isAlpha("aa"));

Assert.assertEquals("AAA", StringUtils.defaultString("AAA"));

Assert.assertEquals("", StringUtils.defaultString(""));

Assert.assertEquals("", StringUtils.defaultString(null));

Assert.assertEquals(6, StringUtils.length("string"));

Assert.assertEquals("fter", StringUtils.substringAfter("after", "a"));

Assert.assertEquals("abc@google.com", StringUtils.trim((" abc@google.com ")));

Assert.assertEquals("google", StringUtils.deleteWhitespace(" goo gle "));


Assert.assertEquals("msle", StringUtils.replace("google", "goog", "ms"));

Assert.assertEquals("bbb", StringUtils.defaultIfBlank("", "bbb"));

Assert.assertEquals(4, StringUtils.indexOfAny("google", new String[] { "le", "ms" }));

Assert.assertEquals(1, StringUtils.indexOfAny("google", new char[] { 'o', 'l' }));

Assert.assertEquals("ass", StringUtils.substringAfterLast("gooogle-glass", "gl"));

Assert.assertEquals("0820", StringUtils.center("82", 4, '0'));


Assert.assertEquals("leass", StringUtils.difference("google", "gleass"));


                 Assert.assertEquals("Google <--> Google <--> Google" , StringUtils.repeat("Google", " <--> ", 3));

                 Assert.assertEquals("Google", StringUtils.removeEnd("Googled", "d"));

                 Assert.assertEquals("Google", StringUtils.chomp("Google\r\n"));


}

}



Posted by '김용환'
,


숫자 앞에 0을 두는 패딩의 예제이다. 

내가 아는 패딩을 추가하는 방법은 3가지이다. 


첫번째, 패딩 문자열에 숫자 문자열을 더하고, 숫자 길이 만큼 뺀다.

두번째, 자리수를 일일이 계산하기 자리수에 따라 0을 앞에 추가한다. 

세번째, StringUtils을 이용한다. 




@Test

public void paddingTest() {

// 문자열을 더해서.

String origin = "60";

String pad = "0000" + origin;

Assert.assertEquals("0060", pad.substring(origin.length()));



// 자리 수 계산 

String num = "60";

int number = Integer.parseInt(num);

if ((int) (number / 100) < 0) {

pad = "00" + num;

}

Assert.assertEquals("0060", pad.substring(origin.length()));



// Apache common lang의 StringUtils 이용하기 

Assert.assertEquals("0060", StringUtils.leftPad("60", 4, "0"));

}

Posted by '김용환'
,



MapUtils 예제이다. (대부분 익숙해지면 되는데, 특별히 한 메소드는 잘 살펴봐야 한다. )


import java.util.Map;


import junit.framework.Assert;


import org.apache.commons.collections.MapUtils;

import org.junit.Test;


import com.google.common.collect.Maps;


public class MapUtilsTest {


@Test

public void test() {

Map<String, Object> map = Maps.newHashMap();

map.put("1", "1");

map.put("3", "3");

map.put("2", "2");

map.put("bool", true);

map.put("int", 1);

System.out.println("empty ? " + MapUtils.isEmpty(map));

System.out.println("not empty ? " + MapUtils.isNotEmpty(map));

MapUtils.debugPrint(System.out, "label", map);

Map<String, Object> fixedSizedMap = MapUtils.fixedSizeMap(map);

try {

fixedSizedMap.put("error", "error"); // exception ocurred

// java.lang.IllegalArgumentException: Cannot put new key/value pair - Map is fixed size

} catch (Exception e) {

System.err.println("exception :" + e);

}

// ------- bool 

System.out.println("boolean--");

// map에 데이터가 있는 경우 

System.out.println(MapUtils.getBoolean(map, "bool")); // true

System.out.println(MapUtils.getBooleanValue(map, "bool")); //true


  // map에 데이터가 없는 경우

System.out.println(MapUtils.getBoolean(map, "nodata"));  // null (주의)

System.out.println(MapUtils.getBooleanValue(map, "nodata")); // false

// map에 데이터가 없으면 default 값 주기

System.out.println(MapUtils.getBoolean(map, "nodata", false));  // false

//---------int

System.out.println("int--");

// map에 데이터가 있는 경우 

System.out.println(MapUtils.getInteger(map, "int")); // true

System.out.println(MapUtils.getIntValue(map, "int")); //true


  // map에 데이터가 없는 경우

System.out.println(MapUtils.getInteger(map, "nodata"));  // null (주의)

System.out.println(MapUtils.getIntValue(map, "nodata")); // false

// map에 데이터가 없으면 default 값 주기

System.out.println(MapUtils.getInteger(map, "nodata", 0));  // false

// -------- sub map

System.out.println("map--");

// key, value를 모두 변경 

Map<String, Object> invertedMap = MapUtils.invertMap(map);

MapUtils.debugPrint(System.out, "inverted map", invertedMap); 

System.out.println();

 // org.apache.commons.collections.map.MultiValueMap 으로 변경 

Map<String, Object> multiValuedMap = MapUtils.multiValueMap(map); 

MapUtils.debugPrint(System.out, "multivalued map", multiValuedMap);

System.out.println();

Map<String, Object> testMap = MapUtils.getMap(map, "2");

System.out.println(testMap); // null

Map<String, Object> subMap = Maps.newHashMap();

subMap.put("subkey1", "1");

subMap.put("subkey2", "2");

map.put("subMap", subMap);

MapUtils.debugPrint(System.out, "sub map", subMap); 

System.out.println();

Map<String, Object> orderedMap = MapUtils.orderedMap(map);

MapUtils.debugPrint(System.out, "ordered map", orderedMap); 

System.out.println();

Map<String, Object> putalledMap = MapUtils.putAll(subMap, new String[][] {{"key1", "5"}, {"key2", "6"}});

MapUtils.debugPrint(System.out, "putalled map", putalledMap); 

MapUtils.verbosePrint(System.out, "putalled map", putalledMap); 

// -- 

Map<String, Object> syncMap = MapUtils.synchronizedMap(map);

org.junit.Assert.assertSame("java.util.Collections$SynchronizedMap", syncMap.getClass().getName());

Object value = null;

MapUtils.safeAddToMap(map, "XXXXXXXXXXX", value); // null이면 ""으로 put이 되게 한다.

org.junit.Assert.assertSame(MapUtils.getObject(map, "XXXXXXXXXXX"), "");

Map<String, Object> unmodifableMap = MapUtils.unmodifiableMap(map);

org.junit.Assert.assertSame("org.apache.commons.collections.map.UnmodifiableMap", unmodifableMap.getClass().getName());

}

}






결과 

empty ? false

not empty ? true

label = 

{

    3 = 3 java.lang.String

    2 = 2 java.lang.String

    1 = 1 java.lang.String

    int = 1 java.lang.Integer

    bool = true java.lang.Boolean

} java.util.HashMap

boolean--

exception :java.lang.IllegalArgumentException: Cannot put new key/value pair - Map is fixed size

true

true

null

false

false

int--

1

1

null

0

0

map--

inverted map = 

{

    3 = 3 java.lang.String

    1 = int java.lang.String

    2 = 2 java.lang.String

    true = bool java.lang.String

    1 = 1 java.lang.String

} java.util.HashMap


multivalued map = 

{

    3 = 3 java.lang.String

    2 = 2 java.lang.String

    1 = 1 java.lang.String

    int = 1 java.lang.Integer

    bool = true java.lang.Boolean

} org.apache.commons.collections.map.MultiValueMap


null

sub map = 

{

    subkey2 = 2 java.lang.String

    subkey1 = 1 java.lang.String

} java.util.HashMap


ordered map = 

{

    3 = 3 java.lang.String

    2 = 2 java.lang.String

    1 = 1 java.lang.String

    int = 1 java.lang.Integer

    bool = true java.lang.Boolean

    subMap = 

    {

        subkey2 = 2 java.lang.String

        subkey1 = 1 java.lang.String

    } java.util.HashMap

} org.apache.commons.collections.map.ListOrderedMap


putalled map = 

{

    subkey2 = 2 java.lang.String

    subkey1 = 1 java.lang.String

    key2 = 6 java.lang.String

    key1 = 5 java.lang.String

} java.util.HashMap

putalled map = 

{

    subkey2 = 2

    subkey1 = 1

    key2 = 6

    key1 = 5

}




MapUtils.getXXX()와 getXXXValue()가 존재하는데, 엄청난 차이가 있다. 

즉, Class로 처리하느냐 Primitive 로 처리하느냐이다. 관련해서 처음에서는 엄청 혼동된다.  


System.out.println(MapUtils.getBoolean(map, "nodata"));  // null (주의)

System.out.println(MapUtils.getBooleanValue(map, "nodata")); // false



예제처럼 getBoolean()할때 Boolean 객체를 리턴하는데, 이 때 null이 될 수 있다. 따라서 boolean primitive 타입을 원한다면 getBooleanValue()를 사용해야 한다. 이를 잘 활용해서 NPE가 발생하지 않도록 해야 한다. 




* 참고


Collection 3.x의 MapUtils.getMap()과 같이 Map을 리턴하는 메소드는 Generic을 지원하지 않는다. 그러나 4.x 부터는 Generic을 지원한다. (3,4의 큰 차이가 Generic) 


Collection 3.x의 MapUtils.getMap()

    public static Map getMap(final Map map, final Object key) {

        if (map != null) {

            Object answer = map.get(key);

            if (answer != null && answer instanceof Map) {

                return (Map) answer;

            }

        }

        return null;

    }


Collections 4.x의 MapUtils.getMap()

https://apache.googlesource.com/commons-collections/+/43e4df85bda71ca1500112912a83d3ed19868c4c/src/main/java/org/apache/commons/collections4/MapUtils.java

    public static <K> Map<?, ?> getMap(final Map<? super K, ?> map, final K key) {

        if (map != null) {

            final Object answer = map.get(key);

            if (answer != null && answer instanceof Map) {

                return (Map<?, ?>) answer;

            }

        }

        return null;

    }







Posted by '김용환'
,




Hbase Rest Client 설정


<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">


    <bean id="hbaseRestClient" class="com.google.HttpComponentsClientFactory">

        <property name="maxTotalConnections" value="1000" />

        <property name="maxConnectionsPerRoute" value="1000" />

        <property name="connectTimeout" value="5000" />

        <property name="socketTimeout" value="5000" />

    </bean>


    <bean id="hbaseRestClientFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">

        <constructor-arg index="0" ref="hbaseRestClient" />

    </bean>


    <bean id="hbaseRestTemplate" class="org.springframework.web.client.RestTemplate">

        <constructor-arg ref="hbaseRestClientFactory" />

        <property name="messageConverters">

            <list>

                <bean class="org.springframework.http.converter.StringHttpMessageConverter">

                    <constructor-arg value="UTF-8"/>

                </bean>

            </list>

        </property>

    </bean>


</beans>


위의 코드 중 아래 코드를 잘 살펴야 한다. 아래 코드는 java 7, java8 에도 동작하는 코드이다. 


  <bean class="org.springframework.http.converter.StringHttpMessageConverter">

                    <constructor-arg value="UTF-8"/>

 </bean>



  <bean class="org.springframework.http.converter.StringHttpMessageConverter">

     <constructor-arg>

<bean class="java.nio.charset.Charset" factory-method="forName">

   <constructor-arg value="UTF-8" />

</bean>

   </constructor-arg> 

</bean>


StringHttpMessageConverter는 인코딩쪽 설정인데, 한글이 깨지면 이 부분 이슈이다.




그러나, StringHttpMessageConverter의 생성자가 Charset 이기 때문에 생성자 아규먼트를 아래와 같이 Charset Type을 넘기면, java 7에서는 작동하나, java 8에서는 Spring boot가 실패한다. 


  <bean class="org.springframework.http.converter.StringHttpMessageConverter">

                   <constructor-arg value="#{T(java.nio.charset.Charset).forName('UTF-8')}"/>

</bean>


특별히 에러 메시지 없이 StringHttpMessageConverter 생성하려다가 container를 destory 한다... ;;;;;




Posted by '김용환'
,

spring @Inject 공부

general java 2014. 12. 9. 01:15

@Inject를 Autowired와 같이 필드에서 많이 사용해서 필드쪽은 잘 알겠는데, 생성자나 메소드쪽은 잘 안써서,, 정리차 대충 글을 찾아보고 써본다.





@Inject는 @Autowired와 비슷한 의미를 가지고 있다.


@Inject 는 필드, 생성자, 메소드에서 쓰이고 있는데, 간단히 살펴본다.

제일 좋은 문서는 api doc 이다. 


https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html


@inject에 대한 api 이다. 

https://docs.oracle.com/javaee/6/api/javax/inject/Inject.html


<필드>

자주 사용하니 패쓰..


<생성자>

일반적으로 생성자 Inject는 여러 생성자 중 하나의 생성자에서 인수를 Inject(주입)시켜 인스턴스를 생성하도록 되어 있다.  


좋은 예제

http://www.tutorialspoint.com/spring/constructor_based_dependency_injection.htm



아래 예제는 Facebook에서 개발한 Swift 의 ThriftServer이다. Spring을 이용하여 ThriftServer를 생성하려면 @Inject가 걸려 있는 생성자를 활용하면 된다. 

http://grepcode.com/file/repo1.maven.org/maven2/com.facebook.swift/swift-service/0.5.0/com/facebook/swift/service/ThriftServer.java?av=f



@Inject

 public ThriftServer(TProcessor processor, ThriftServerConfig config, @ThriftServerTimer Timer timer)

{

...

}



<메소드>

설명보다 아래 예제에서 잘 설명됨 (prototype, look-up)


좋은 예제

http://java.dzone.com/articles/method-injection-spring


http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-method-injection








Posted by '김용환'
,


commons-lang 2.x를 쓰다가 commons-lang 3.x 으로 바꿀 때 유의할 사항은 common-lang 3.x는 더이상 하위버전을 지원하지 않는다. 그래서 과거에 한번 장애를 맞이한적이 있었다.

또한 commons-lang 3.x에서는 명시적으로 과거와 다른 패키지임을 나타내기 위해서 org.apache.commons.lang3 를 쓰도록 되어 있다. 



http://commons.apache.org/proper/commons-lang/

Note that Lang 3.0 (and subsequent versions) use a different package (org.apache.commons.lang3) than the previous versions (org.apache.commons.lang), allowing it to be used at the same time as an earlier version.



http://commons.apache.org/proper/commons-lang/article3_0.html

The big story

Lang is now Java 5 based. We've generified the API, moved certain APIs to support varargs and thrown out any features that are now supported by Java itself. We've removed the deprecated parts of the API and have also removed some features that were deemed weak or unnecessary. All of this means that Lang 3.0 is not backwards compatible.

To that end we have changed the package name, allowing Lang 3.0 to sit side-by-side with your previous version of Lang without any bad side effects. The new package name is the exciting and originalorg.apache.commons.lang3. This also forces you to recompile your code, making sure the compiler can let you know if a backwards incompatibility affects you.

As you'd expect, there are also new features, enhancements and bugs fixed.

Posted by '김용환'
,

webhooks의 content type이 application/json인 경우, jenkins에서 hook 결과가 아래 IllegalArgumentException이 발생되어 삽질을 할 수 있다. 


Caused by: java.lang.IllegalArgumentException: Not intended to be browsed interactively (must specify payload parameter)

at com.cloudbees.jenkins.GitHubWebHook.doIndex(GitHubWebHook.java:154)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:601)

at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:298)

at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:161)

at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:96)

at org.kohsuke.stapler.MetaClass$2.dispatch(MetaClass.java:164)

at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:733)




관련 내용을 살펴보기 위해 검색했다.


http://developer.cloudbees.com/bin/view/DEV/GitHub+Commit+Hooks+HOWTO

http://stackoverflow.com/questions/15429448/how-to-configure-cloudbees-jenkins-to-trigger-build-on-push-to-github

http://ics-software-engineering.github.io/play-example-continuous-integration/


관련해서 특별한 문제점을 찾을 수 없었다. 



참고로 GitHubWebHook plugin 소스를 확인해보니. payload 정보를 읽지 못한 부분이었다. 


 public void doIndex(StaplerRequest req) {

151

152         String eventType = req.getHeader("X-GitHub-Event");

153         if ("push".equals(eventType)) {

154             String payload = req.getParameter("payload");

155             if (payload == null) {

156                 throw new IllegalArgumentException("Not intended to be browsed interactively (must specify payload parameter). " +

157                         "Make sure payload version is 'application/vnd.github+form'.");

158             }

159             processGitHubPayload(payload,GitHubPushTrigger.class);

160         } else if (eventType != null && !eventType.isEmpty()) {

161             throw new IllegalArgumentException("Github Webhook event of type " + eventType + " is not supported. " +

162                     "Only push events are current supported");

163         } else {

164             //Support github services that don't specify a header.

165             //Github webhook specifies a "X-Github-Event" header but services do not.

166             String payload = req.getParameter("payload");

167             if (payload == null) {

168                 throw new IllegalArgumentException("Not intended to be browsed interactively (must specify payload parameter)");

169             }

170             processGitHubPayload(payload,GitHubPushTrigger.class);

171         }




결론은 특수 문자 및 한글 이슈로 인해서 application/json이 동작이 안될 수 있다.  

Webhooks/Manage webhook의 Content type에 application/x-www-form-urlencoded 를 설정하고 webhook 테스트를 진행해보니. 잘 동작되었다.

Posted by '김용환'
,

ubuntu에서 $ apt-get install jenkins 한 후, 새로운 버전으로 설치를 위해 

$ apt-get remove jenkins 하고 


$ apt-get install 하면 아래 에러가 발생



stdout: Reading package lists...

Building dependency tree...

Reading state information...

The following packages were automatically installed and are no longer required:

  libjna-java libcommons-jxpath-java libmaven-dependency-tree-java

  libjaxp1.3-java junit4 gcj-4.6-jre-lib libmaven-plugin-testing-java

  libplexus-archiver-java librhino-java libplexus-containers-java

  libwagon-java libmodello-java gcj-4.6-base libxerces2-java

  libavalon-framework-java libgcj-bc libplexus-classworlds-java

  libmaven2-core-java libhttpclient-java libjffi-jni libcommons-beanutils-java

  libxalan2-java libcommons-jexl-java libjnr-posix-java junit

  libplexus-cipher-java libconstantine-java bsh-gcj libplexus-build-api-java

  libplexus-i18n-java libplexus-interactivity-api-java

  libjenkins-remoting-java libcommons-cli-java java-wrappers

  libmaven-common-artifact-filters-java libcommons-logging-java jenkins-cli

  libxbean-java libcommons-net2-java libmaven-enforcer-plugin-java

  libsaxon-java libgcj12 libitext1-java libplexus-ant-factory-java ant

  libplexus-container-default-java libjsch-java bsh libeasymock-java

  libxml-commons-resolver1.1-java ant-optional fop libbsf-java

  libapache-pom-java libplexus-io-java libplexus-bsh-factory-java

  libclassworlds-java libxml-commons-external-java

  libplexus-interpolation-java libice6 libgoogle-collections-java

  libargs4j-java libanimal-sniffer-java libasound2 libhttpcore-java

  libservlet2.5-java libcommons-httpclient-java libcommons-vfs-java

  libjsr305-java libslf4j-java libasm3-java libjsoup-java libregexp-java

  libfop-java libcommons-configuration-java libxtst6 rhino libjffi-java

  libxmlgraphics-commons-java libcommons-codec-java jenkins-common

  libcommons-lang-java libhamcrest-java libsm6 libnetbeans-cvsclient-java

  libcommons-parent-java libcommons-collections3-java libgcj-common

  libplexus-utils-java libplexus-sec-dispatcher-java libjaffl-java

  libmaven-scm-java libdoxia-java libcommons-digester-java libbatik-java

  libxt6 libbackport-util-concurrent-java libjetty-java liblog4j1.2-java

  libjline-java libcommons-io-java libmaven-invoker-java libganymed-ssh2-java

Use 'apt-get autoremove' to remove them.

The following NEW packages will be installed:

  jenkins

0 upgraded, 1 newly installed, 0 to remove and 169 not upgraded.

Need to get 0 B/61.8 MB of archives.

After this operation, 67.9 MB of additional disk space will be used.

(Reading database ... 56700 files and directories currently installed.)

Unpacking jenkins (from .../archives/jenkins_1.580_all.deb) ...

dpkg: error processing /var/cache/apt/archives/jenkins_1.580_all.deb (--unpack):

 trying to overwrite '/usr/share/jenkins/jenkins.war', which is also in package jenkins-common 1.424.6+dfsg-1ubuntu0.2

dpkg-deb: error: subprocess paste was killed by signal (Broken pipe)

Errors were encountered while processing:

 /var/cache/apt/archives/jenkins_1.580_all.deb


msg: 'apt-get install 'jenkins' ' failed: E: Sub-process /usr/bin/dpkg returned an error code (1)



원인은 jenkins-common은 하위버전, 새로 설치하려는 jenkins 버전은 상위버전이라서 에러가 발생했다. 

그 부분을 보정하니 에러는 더이상 발생하지 않았다. 


$ apt-get remove jenkins-common

$ apt-get install jenkins



Posted by '김용환'
,


jenkins plugin을 jenkins cli 실패가 발생할 수 있다. 



$ java -jar jenkins-cli.jar -s http://localhost:8080 install-plugin cmd

cmd is neither a valid file, URL, nor a plugin artifact name in the update center

No update center data is retrieved yet from: http://updates.jenkins-ci.org/update-center.json

cmd looks like a short plugin name. Did you mean 'null'?



그럴 때는 아래 링크를 참조해서 설치한다. 

http://pastebin.com/69niu55N 

pastebin 이라 언제든지 없어질 수 있는지라. 기록을 남둠. l
( 1.461을 사용중인데..ist-plugins command가 사라졌다. )

$ java -jar jenkins-cli.jar -s http://localhost:9000 install-plugin findbugs
findbugs is neither a valid file, URL, nor a plugin artifact name in the update center
No update center data is retrieved yet from: http://updates.jenkins-ci.org/update-center.json
findbugs looks like a short plugin name. Did you mean 'null'?
 
 
# Specifying a full URL works!
$  java -jar jenkins-cli.jar -s http://localhost:9020 install-plugin http://updates.jenkins-ci.org/download/plugins/AdaptivePlugin/0.1/AdaptivePlugin.hpi
 
# Get the update center ourself
$ wget -O default.js http://updates.jenkins-ci.org/update-center.json
 
# remove first and last line javascript wrapper
sed '1d;$d' default.js > default.json
 
# Now push it to the update URL
curl -X POST -H "Accept: application/json" -d @default.json http://localhost:9020/updateCenter/byId/default/postBack --verbose
* About to connect() to localhost port 9020 (#0)
*   Trying ::1... connected
* Connected to localhost (::1) port 9020 (#0)
> POST /updateCenter/byId/default/postBack HTTP/1.1
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3
> Host: localhost:9020
> Accept: application/json
> Content-Length: 253822
> Content-Type: application/x-www-form-urlencoded
> Expect: 100-continue
>
* Done waiting for 100-continue
< HTTP/1.1 200 OK
< Server: Winstone Servlet Engine v0.9.10
< Content-Type: text/plain;charset=UTF-8
< Connection: Close
< Date: Fri, 01 Apr 2011 13:03:41 GMT
< X-Powered-By: Servlet/2.5 (Winstone/0.9.10)
 
# Now it finds the plugin by name
$ java -jar jenkins-cli.jar -s http://localhost:9020 install-plugin findbugs
Installing findbugs from update center
 
$  java -jar jenkins-cli.jar -s http://localhost:9020 safe-restart
hudson.lifecycle.RestartNotSupportedException: Restart is not supported on Mac OS X
 
$ java -jar jenkins-cli.jar -s http://localhost:9020 reload-configuration




Posted by '김용환'
,



play 이제 시작한지 일주일이다. 잘 모르면서 쓰고 있다. ^^;;;;;;;;

play의 controller 인 Application에서 index 메소드를 호출할 때 test 메소드를 호출하고 rendering하면 에러가 발생한다. 


10 public class Application extends Controller {

 11

 12     public static void index() {

 13         test();

 14     }

 15

 16     public static void test() {

 17       render();

 18     }

 19

 20 }




에러의 내용은 다음과 같다. 


Template not found

The template Application/test.html does not exist.



play.exceptions.TemplateNotFoundException: Template not found : Application/test.html

at play.mvc.Controller.renderTemplate(Controller.java:668)

at play.mvc.Controller.renderTemplate(Controller.java:641)

at play.mvc.Controller.render(Controller.java:696)

at controllers.Application.test(Application.java:17)

at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557)

at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508)

at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484)

at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479)

at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)

at Invocation.HTTP Request(Play!)



=> 코드는 서로간의 호출이 있을 수 없도록 해야 한다.

10 public class Application extends Controller {

 11

 12     public static void index() {

 13         render();

 14     }

 15

 16     public static void test() {

 17       render();

 18     }

 19

 20 }




그리고, play framwork 와 yarouter를 이용해서 사용하는 경우에도 마찬가지이다. 똑같이 에러가 발생한다. 


public class UserController {

..

@Get("/user/{userId}) 

public static void getUser(String userId) {

   getuserSeo(userId);

}


@Get("/user/seo/{userId}")   // 나중에 오픈할 url 

public static void getUserSeo(String userId) {

...

}


}



에러 내용은 다음과 같다.



[r.ResponseUtils$ErrorResult] logErrorMessage (111): play.exceptions.NoRouteFoundException: No route found




Caused by: play.exceptions.NoRouteFoundException: No route found

at play.mvc.Controller.redirect(Controller.java:602) ~[play-1.2.5.3.jar:na]

at play.mvc.Controller.redirect(Controller.java:544) ~[play-1.2.5.3.jar:na]




-> 코드는 아래와 고쳐져야 한다. (사실 추후 오픈할 때 사용하려고 했는데.. 나중에 오픈할 때 private을 public으로 수동으로 고쳐야 할 것 같음)


public class UserController {

..

@Get("/user/{userId}) 

public static void getUser(String userId) {

   getuserSeo(userId);

}


@Get("/user/seo/{userId}")  // 나중에 오픈할 url

private static void getUserSeo(String userId) {

..

}


}



Posted by '김용환'
,