Tanuki Service Wrapper는 linux daemon 처럼 쓸 수 있다.

기능은 다음과 같다.

In addition to supporting Java Service Wrapper development, get access to professional features:

  • Alert emails (Professional): Sleep safe at night knowing that you will be notified by email whenever anything happens with your application.
  • Event commands (Professional): Get the ability to execute arbitrary system commands in response to a wide range of JVM and Wrapper state changes.
  • Timed events (Professional): Ability to schedule JVM restarts, shutdowns, and thread dumps at specific times or intervals.
  • Relative Memory Limits: Ability to set initial and maximum memory levels based on the total amount of system memory.
  • Consoleless binary: Ability to run the Wrapper without a console as a Windows application.

별 것은 없는데..
syslog를 이용할 수 있다는 말에 혹 마음이 간다.
또한, 톰캣을 데몬처럼 쓰게하고 restart할 때에 대한 개념을 스크립트가 아닌 daemon처럼 쓸 때 유용할 수 있겠다라는 생각이 든다..



Using Tanuki Software's Java Service Wrapper

 

Have a look at http://wrapper.tanukisoftware.org/ - the Java Service Wrapper is a very powerful service wrapper for any Java application and works fine with JBoss.

 

You can also have a look at the Windows Java Service page, which has more instructions and configuration options for the Java Service Wrapper. 

 

A basic wrapper.conf would look like this:

 


wrapper.java.command=/usr/java/bin/java
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=run.jar
wrapper.java.classpath.3=/usr/java/lib/tools.jar

wrapper.java.library.path.1=../lib

wrapper.java.additional.1=-server
wrapper.java.additional.2=-Dprogram.name=run.sh

wrapper.java.initmemory=256
wrapper.java.maxmemory=256

wrapper.app.parameter.1=org.jboss.Main
wrapper.app.parameter.2=-c
wrapper.app.parameter.3=default

wrapper.console.format=PM
wrapper.console.loglevel=INFO

wrapper.logfile=wrapper.log
wrapper.logfile.format=LPTM
wrapper.logfile.loglevel=INFO
wrapper.logfile.maxsize=1m
wrapper.logfile.maxfiles=1

wrapper.syslog.loglevel=NONE


나름 상도 받구 열심히 하는 것 같다.
이런 솔루션을 만들어 봐야겠다.. 스크립트 기반보다는 정형화된 표준형식으로 사용하고 싶다라는 생각이 든다.

Awards

Posted by '김용환'
,

https://issues.apache.org/bugzilla/show_bug.cgi?id=49236

톰캣의 jar안에 META-INF/INDEX.LIST 파일이 존재하는데, 이를 생성하는  톰캣 ant의 <jar index="true"/> 에 대한 이야기이다. 내용을 정리해서 올린다.


톰캣 Committer 중의 하나인 Konstantin Kolinko는 jar indexing이 로딩 속도를 빠르게 빠르게 하기 위해서 jar index 태그를 사용했다고 한다.

Jar 스펙 (http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#JAR Index) 을 참조

  • INDEX.LIST
This file is generated by the new "-i" option of the jar tool, which contains location information for packages defined in an application or extension.  It is part of the JarIndex implementation and used by class loaders to speed up their class loading process.


Konstantin Kolinko는 더이상 속도 개선이 없다고 한다. 사실 jar 자체가 이미 zip 인덱스를(central driectory) 가지고 있기 때문이기 때문이라고 얘기한다.

zip-application-note 자료
http://www.pkware.com/documents/casestudies/APPNOTE.TXT

zip 도식화
http://en.wikipedia.org/wiki/ZIP_%28file_format%29#Technical_information

ZIPformat.jpg

ZipEntry의 getEntry(String) 메소드와 같이 random access 을 하기 전에 이미 java는 jar파일의 central directory를  메모리에 로딩하기 때문에 속도가 빠를 수 밖에 없다.

또한, URLClassLoader에서 로딩할 때마다 index.list 파일을 한 번 더 체크하기 때문에 성능 이슈가 있을 수 있다

index.list 파일은 jar 의 MANIFEST.MF파일의 class-path와 conflict 될 수 있는 소지가 있고, jar 파일의 이름을 변경함으로서, side effect가 생길 수 있다.

그래서 tomcat의 빌드시 jar태그의 index속성을 "false"로 지정한다.
Posted by '김용환'
,

http://static.springsource.org/spring/docs/1.2.9/reference/beans.html

Specifying the target bean by using the bean attribute of the ref tag is the most general form, and will allow creating a reference to any bean in the same BeanFactory/ApplicationContext (whether or not in the same XML file), or parent BeanFactory/ApplicationContext. The value of the bean attribute may be the same as either the id attribute of the target bean, or one of the values in the name attribute of the target bean.

  <ref bean="someBean"/>

Specifying the target bean by using the local attribute leverages the ability of the XML parser to validate XML id references within the same file. The value of the local attribute must be the same as the id attribute of the target bean. The XML parser will issue an error if no matching element is found in the same file. As such, using the local variant is the best choice (in order to know about errors are early as possible) if the target bean is in the same XML file.

  <ref local="someBean"/>

ApplicationContext 또는 BeanFactory 안에서 사용할 때는 bean을 쓰고 싶을 때는 ref bean 태그를 사용한다.
하지만, 하나의 파일(xml) 안에서만 쓰고 싶을 때는 ref local 태그를 쓴다.

특정 플랫폼에서 사용될 때, 같은 이름을 주어서 서로 Conflict나 예기치 않은 일이 일어나지 않는 것이 중요하기 때문에..
하나의 파일에서 처리하는 reference bean이 많을 때는 local을 쓰는 것이 좋다.

Posted by '김용환'
,


ant을 쓸 때마다 불편함이 넘어온다

condition은 그 불편함의 예..

일반 언어처럼 쓸 수 있도록 하는 jar가 있는데. 그게 바로 ant-contrib 이다.
http://ant-contrib.sourceforge.net/


condition 이 이렇게 쉽게 바꿔 쓸 수 있다.


<if>
<equals arg1="${target}" arg2="windows" />
<then>
<antcall target="build-windows"/>
</then>
<else>
<antcall target="build-solaris"/>
</else>
</if>

그외에도 compile, cc, 통신 을 쉽게 쓸 수 있도록 지원한다.

더이상 지원하지 않지만, ant를 편하게 쓸 수 있어서. 강추!!
Posted by '김용환'
,


톰캣 7에는 Servlet 3.0 Spec를 지원하게 됩니다. 관련해서 맛보기 시리즈를 추가할까 합니다.

(Serlvet 3.0 Spec에 참여하는 분들이 톰캣 7 Committer 이기 때문에 빨리 맛보게 되는 장점이 있는 것 같습니다.

사실 정확히 말하면, GlassFish 3가 제일 먼저 적용되었습니다. Sun(이젠 Oracle) 개발자들이 톰캣 7 Commit로 활용합니다. ^^)

 

문서는 아래를 참조하시면 됩니다.

The Servlet 3.0 API

http://jcp.org/aboutJava/communityprocess/final/jsr315/index.html

 

Servlet 3.0 Final realease8 Annotations and pluggability 8.1 annotations에 자세한 Annotation 을 쓰는 부분이 나옵니다.

 

Meta data를 제공 함으로서, web.xml에 정보를 저장하지 않아도 쓸 수 있도록 지원합니다.

 

1.     서블릿 정의 (@WebServlet)

1)     그냥 정의

@WebServlet(/foo)

public class CalculatorServlet extends HttpServlet{

//...

}

 

2)     Attribute 이용 정의

@WebServlet(name=MyServlet, urlPatterns={"/foo", "/bar"})

public class SampleUsingAnnotationAttributes extends HttpServlet{

public void doGet(HttpServletRequest req, HttpServletResponseres) {

}

}

 

3)     urlPatterns, initParams, WebInitParam를 사용하여 세밀한 설정이 가능

@WebServlet(name="mytest",
        urlPatterns={"/myurl"},
        initParams={ @WebInitParam(name="n1", value="v1"), @WebInitParam(name="n2", value="v2") })

    public class TestServlet extends javax.servlet.http.HttpServlet {
        ....
    }

ð  web.xml에서 <web-app> 태그 안에서 servlet를 정의한 효과와 동일합니다. 설정이 Annotation으로 적용됩니다.

<servlet>

<servlet-name>mytest</servlet-name>

<servlet-class>TestServlet</servlet-class>

 <init-param>
        <param-name>n1</param-name>
        <param-value>v1</param-value>
   </init-param>
   <init-param>
        <param-name>n2</param-name>
        <param-value>v2</param-value>
    </init-param>

</servlet>

 

<servlet-mapping>

<servlet-name>mytest</servlet-name>

    <url-pattern>/myurl</url-pattern>

</servlet-mapping>

 

2.     WebListener 정의

@WebListener

public class MyListener implements ServletContextListener{

public void contextInitialized(ServletContextEvent sce) {

ServletContext sc = sce.getServletContext();

sc.addServlet("myServlet", "Sample servlet", "foo.bar.MyServlet", null, -1);

sc.addServletMapping("myServlet", new String[] { "/urlpattern/*" });

}

}

 

3.     WebFilter 정의

@WebFilter(/foo)

public class MyFilter implements Filter {

public void doFilter(HttpServletRequest req, HttpServletResponse res) {

...

}

}

 

4.     MultipartConfig 정의
mime/multipart
지원하여 파일 업로드를 쉽게 할 수 있도록 지원. ( Utility가 없어서 따로 만들었었습니다.)

@MultipartConfig(location="/data")

public class MyServlet extends HttpServlet {

  public void service(HttpServletRequest req, HttpServletResponse resp)

    throws ServletException, IOException {

    //target directory and location are the same. The file is moved(not copied)

    req.getPart("content").write("/data/file.dat");

  }

}

 

5.     기타 annotation
Spec 15.5
에 정의 됨

 

참고

1.     Serlvet 3.0 Specifiation Final Release

2.     http://blogs.sun.com/swchan/entry/servlet_3_0_annotations (최근에 바뀐 Spec내용을 반영되지 않았음. 내용만 이해하면 될 듯)

3.     http://blog.caucho.com/?p=237

 

 

 

최근 트렌드인 Struts Spring, tapestry처럼 Annotation 기반으로 쓸 수 있도록 배려하는 것이 보입니다.

(지극히 개인적인 생각입니다만… 개발입장에서는 Annoation 기반 정의가 편합니다. 나눠서 개발할 때도 conflict가 나지 않으니 좋을 듯 합니다..

반면, 유지보수 입장에서는 문제 해결이나 흐름을 보는데 시간이 조금 더 소요되는 단점이 있습니다.

'general java' 카테고리의 다른 글

[Spring] ref local과 ref bean의 차이점  (0) 2010.05.13
Ant의 불편함을 최소화- Ant Contrib  (0) 2010.05.13
java application 서버 사용 통계  (0) 2010.03.30
lucene  (0) 2010.03.08
JMX 모니터링중 에러  (0) 2009.12.30
Posted by '김용환'
,


대충 아는 선에서 본 어플리케이션 서버의 통계를 봄..
http://en.wikipedia.org/wiki/Comparison_of_application_servers#Java_EE

indeed.com에서 job trends를 비교하니..

WebSphere > WebLogic > Tomcat > Jboss >>>>  Resin, Jetty, glassfish, Geronimo




'general java' 카테고리의 다른 글

Ant의 불편함을 최소화- Ant Contrib  (0) 2010.05.13
Tomcat7 - Serlvet 3.0 맛보기 (Annotation) #1  (1) 2010.04.20
lucene  (0) 2010.03.08
JMX 모니터링중 에러  (0) 2009.12.30
Lucene에서 한글 내용  (0) 2009.12.24
Posted by '김용환'
,

lucene

general java 2010. 3. 8. 16:49

http://knol.google.co.kr/k/lucene-in-action#
http://onjava.com/pub/a/onjava/2006/01/18/using-lucene-to-search-java-source.html
http://today.java.net/pub/a/today/2003/07/30/LuceneIntro.html
http://markmail.org/message/fzrx7dmw7bqiacgl#query:lucene%20standardanalyzer%20underscore+page:1+mid:mx53rsufocco2wjq+state:results
=> underscope 는 검색되게.
http://www.jazzvm.net/board/view.jazz?code=864593&seq=827&currentPage=1&currentBlock=1
=> 예전 lucene jj 컴파일하기
http://www.mhaller.de/archives/119-Date-ranges-in-Lucene.html
=> 파일 검색시 시간 범위의 파일 검색


특수문자 검색을 하는 것과 안하도록 하는 것은 약간의 시간차가 난다. 0.5s에서 1s 사이. 하지만.. 특수문자를 define해서 검색하도록 하는 것이 좋은 듯 하다..


Posted by '김용환'
,


java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:

           java.net.ConnectException: Connection refused: connect

           at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)

           at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)

           at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)

           at sun.rmi.server.UnicastRef.invoke(Unknown Source)

           at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)

           at javax.management.remote.rmi.RMIConnector.getConnection(Unknown Source)

           at javax.management.remote.rmi.RMIConnector.connect(Unknown Source)

           at javax.management.remote.JMXConnectorFactory.connect(Unknown Source)

           at javax.management.remote.JMXConnectorFactory.connect(Unknown Source)

           at DataJMXConnector$1.run(AAA.java:52)

           at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

           at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)

           at java.util.concurrent.FutureTask.run(Unknown Source)

           at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)

           at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

           at java.lang.Thread.run(Unknown Source)

Caused by: java.net.ConnectException: Connection refused: connect

           at java.net.PlainSocketImpl.socketConnect(Native Method)

           at java.net.PlainSocketImpl.doConnect(Unknown Source)

           at java.net.PlainSocketImpl.connectToAddress(Unknown Source)

           at java.net.PlainSocketImpl.connect(Unknown Source)

           at java.net.SocksSocketImpl.connect(Unknown Source)

           at java.net.Socket.connect(Unknown Source)

           at java.net.Socket.connect(Unknown Source)

           at java.net.Socket.<init>(Unknown Source)

           at java.net.Socket.<init>(Unknown Source)

           at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)

           at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)

           ... 16 more


다른 것은 괜찮은데, 한 대의 서버에서만 이렇게 에러가 났다..
/etc/hosts 파일이 문제인 것임. 파일이 잘못되어 있거나 localhost 외에 127.0.0.1 로 되어 있지 않도록 한다. aaabbb001 서버라면, 127.0.0.1 aaabbb001 이 아닌 public ip로 지정해야 한다.
127.0.0.1 aaabbb001 이렇게 하면서 실제 jmx 연결하면서 jmx 클라이언트의 localhost 를 보는 황당한 일이 있었다..

Posted by '김용환'
,


리눅스 환경이 Euc-kr 이고,
env | grep LANG
LANG=ko_KR.eucKR

svn에서 체크아웃받은 소스를 검색하는데, 한글이 깨진다.

해결 방법은 KSC5601로 파일을 읽으면 한글 안깨진다.ㅡ.ㅡ;



doc.add(new Field("contents", new FileReader(file)));
=>
doc.add(new Field("contents", new InputStreamReader(new FileInputStream(file), "KSC5601")));


Posted by '김용환'
,

Apache Mina  1.1.7
Java 1.6.0-13
Windows 7

XP에서 윈도우 7으로 전환했는데. mina를 테스트하다가 이상한 것이 생겼다.
I changed my windows into Windows 7 from Windows XP.

재현 시나리오는 이유없이 그냥 "Invalid argument" Exception이 나오는 것이 아닌가? 될 때도 있고 안 될 때도 있고.. 그랬다.



Exception in thread "Thread-4" org.apache.mina.common.RuntimeIOException: java.net.SocketException: Invalid argument: sun.nio.ch.Net.setIntOption
at org.apache.mina.transport.socket.nio.SocketSessionImpl$SessionConfigImpl.setKeepAlive(SocketSessionImpl.java:252)
at org.apache.mina.transport.socket.nio.SocketSessionImpl.<init>(SocketSessionImpl.java:94)
at org.apache.mina.transport.socket.nio.SocketConnector.newSession(SocketConnector.java:350)
at org.apache.mina.transport.socket.nio.SocketConnector.processSessions(SocketConnector.java:290)
at org.apache.mina.transport.socket.nio.SocketConnector.access$900(SocketConnector.java:53)
at org.apache.mina.transport.socket.nio.SocketConnector$Worker.run(SocketConnector.java:395)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.net.SocketException: Invalid argument: sun.nio.ch.Net.setIntOption
at sun.nio.ch.Net.setIntOption0(Native Method)
at sun.nio.ch.Net.setIntOption(Net.java:152)
at sun.nio.ch.SocketChannelImpl$1.setInt(SocketChannelImpl.java:372)
at sun.nio.ch.SocketOptsImpl.setBoolean(SocketOptsImpl.java:38)
at sun.nio.ch.SocketOptsImpl.keepAlive(SocketOptsImpl.java:92)
at sun.nio.ch.OptionAdaptor.setKeepAlive(OptionAdaptor.java:139)
at sun.nio.ch.SocketAdaptor.setKeepAlive(SocketAdaptor.java:322)
at org.apache.mina.transport.socket.nio.SocketSessionImpl$SessionConfigImpl.setKeepAlive(SocketSessionImpl.java:248)
... 7 more



확인을 해보니. 이미 아파치 jira에 있던 내용이었다.
I checked in google, that issue was in apache jira.

https://issues.apache.org/jira/browse/DIRMINA-379


Solution  :


 내가 사용했던 코드는 다음과 같다.
I trited to use static class member when I used SocketConnector in Mina.
public class ImageUploaderConnector {
...
 private static SocketConnector socketConnector;
 private static SocketConnectorConfig config;
 private static DefaultIoFilterChainBuilder filterChainBuilder = new DefaultIoFilterChainBuilder();
 private static  final SocketHandler HANDLER = new SocketHandler();

=>

원인은 아마도 static 메소드안에서 초기화와 set을 하면서 동기화 문제가 생긴 것 같다.
I think the exception was confliction between initialization and set method calling.

Exception 나는 것을 확인하기 위해서 static을 지워보니. 더이상 에러가 나지 않는다!!
I deleted static, no longer exception thrown!!
Every create a new SocketConnector instance for every request, the exception never is thrown..


public class ImageUploaderConnector {
...
 private SocketConnector socketConnector;
 private SocketConnectorConfig config;
 private DefaultIoFilterChainBuilder filterChainBuilder = new DefaultIoFilterChainBuilder();
 private final SocketHandler HANDLER = new SocketHandler();



At below, someone says..

 see this as well (Windows 2000, 2003 Server and Vista), but only when reusing one SocketConnector for many client sessions, connecting clients very quickly in sequence.

If I create a new SocketConnector instance for every client connection, the problem goes away. If this is due to the overhead of creating a new SocketConnector for each client, I do not know. I imagined one SocketConnector was multi-thread safe for creating many client connections in parallell (ref. the connectQueue etc ..) ?

(http://old.nabble.com/-jira--Created:-(DIRMINA-379)-setKeepAlive-setTcpNoDelay-and-exceptions-in-Windows-Vista-td10689620i20.html)

Posted by '김용환'
,