블로그 이미지

GUEST

java 2019. 8. 13. 21:52

javap - java version확인

@class 파일로부터 java 버전을 확인하는 방법


javap -verbose {CLASS_NAME} |grep 'major version' 

major version : 50 //java1.6
major version : 51 //java1.7
major version : 52 //java1.8





@응용
- class파일 목록을 만들고 version확인하기.

1) 목록 만들기
find [.|/../WEB-INF] -type f -name '*.class' > ./classes.list



2) version 확인
for c in `classes.list`
do

STR1=`javap -verbose ${c} |grep 'major version'`     //결과를 변수로 받아서
echo -c "$e\t$STR1"                                  //tab구분자로 출력하기

done


3) 1+2

find [.|/../WEB-INF] -type f -name '*.class' > ./classes.list &    //background

BACK_PID=$!

wait $BACK_PID    //끝날 때까지 대기


for c in `classes.list`

do

STR1=`javap -verbose ${c} |grep 'major version'`
echo -c "$e\t$STR1"  >> ./version.out                //version.out에 출력

done


cf) linux script.

,
java 2009. 1. 23. 15:21

[FTP]자바로 구현한 FTP


http://finj.sourceforge.net/

http://j-ftp.sourceforge.net/

http://jvftp.sourceforge.net/

sun에서 제공하는 것도 있단다. j2se 기본 패키지에는 없다.  finj는 sun제공 package를 wrapping한 것 같다.

apache commons sub-project 'net' 에도 ftp 기능이 있다.

net에는 기타 여러 재미있는 기능들이 포함되어 있다.

시간날 때 짬짬이 보면 좋겠다.
,
java 2008. 10. 2. 13:45

[WAS]struts2 간단 setting


http://struts.apache.org/2.1.2/docs/simple-setup.html

struts를 가볍게 써보려고 하다가 필수 jar들이 생각이 안 나서 다시 찾았다.

struts2-core.jar
xwork.jar
ognl.jar
freemarker.jar
commons-logging.jar
web.xml
struts.xml



요렇게 파일은 필요하고
[service name]/WEB-INF/web.xml에는 아래와 같이 적는다.

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>My Application</display-name>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

struts의 필터는 결국 request를 가로채고 uri의 String을 struts-config.xml의 action과 비교하여 dispatching하는 것 같다. url-pattern을 조작하면 특정 directory밑으로만 struts의 설정이 적용될 것이다.

다음은 struts confing인데 [service-name]/WEB-INF/classes/struts.xml 이다.
이름이 struts-config.xml에서 바뀐 것 같은데 바꿔서 작동하는 지는 시도해 보지 않았다. xml element쓰는 법이 바뀌었는지는 확인해 봐야겠다.

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts><!-- Configuration for the default package. -->
<package name="default" extends="struts-default">
         ...
</package>
</struts>


,
java 2008. 9. 17. 23:08

[WAS]jndi 설정

http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

http://java.sun.com/products/jndi/tutorial/index.html


jndi를 이용하여 DBPooling외에도 초기화된 bean객체를 생성하거나, javaMail의 session을 얻어오거나 할 수도 있다.

JDBC Data Source 얻어오는 것을 보자.

1. JDBC Driver 설치

연결하려는 DB의 jdbc driver를 $CATALINA_HOME/common/lib에 넣는다.


2. [WebApp]/WEB-INF/web.xml에 소스에서 요청할 jndi Resource를 명기한다.

<resource-ref>
  <description>
    Resource reference to a factory for java.sql.Connection
    instances that may be used for talking to a particular
    database that is configured in the server.xml file.
  </description>
  <res-ref-name>
    jdbc/EmployeeDB
  </res-ref-name>
  <res-type>
    javax.sql.DataSource
  </res-type>
  <res-auth>
    Container
  </res-auth>
</resource-ref>



3. 실제 사용은 아래와 같이 한다.

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
  envCtx.lookup("jdbc/EmployeeDB");

Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();



4. 실제 jndi Resource는 [WebApp]/META-INF/context.xml에 아래와 같이 선언해 준다.

<Context ...>
  ...
  <Resource name="jdbc/EmployeeDB" auth="Container"
            type="javax.sql.DataSource" username="dbusername" password="dbpassword"
            driverClassName="org.hsql.jdbcDriver" url="jdbc:HypersonicSQL:database"
            maxActive="8" maxIdle="4"/>
  ...
</Context>

cf) 나는... tomcat/conf/Catalina/localhost/[WEB-APP].xml 에 있는 Context에 작성했다.


http://markmail.org/message/vigu4iein5d3xvkh

http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html

https://issues.apache.org/jira/browse/DBCP-134?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel



요것도 보자. 보통 Connection을 얻어서 try절 내에서 close한 후 finally에서 확인사살을 하는데
이 때 already closed connection error가 생길 수 있다.
이 때의 해결법.


,
java 2008. 9. 17. 18:33

[WAS]Tomcat Filter

http://www.ibm.com/developerworks/java/library/j-tomcat/

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html

servlet 2.3에서 구현할 수 있는 필터는 Apache, IIS 또는 Netscape server에서 구현된 것과는 달리 어쩌구 저쩌구... 효과적이고 좋다.



Chain of calls
servlet2.3에서는 javax.servlet.Filter interface를 구현하며 아래 세 가지 메소드가 구현되어야 한다.

1. void doFilter(ServletRequest, ServletResponse, FilterChain)
    filter action이 실행될 때 호출되는 메소드. upstream filter가 호출하고 FilterChain 객체 내에 downstream filter가 호출할 정보가 들어 있다. 보통 아래와 같은 내용을 구현한다.
    1) request검증
    2) request 객체 가공
    3) response 객체 가공
    4) FilterChain 객체를 사용하여 연결된 다음 작업 실행(chain.doFilter)
       또는 다음 작업을 막음
    5) 작업 수행 후, response의 header정보를 직접 가공

2. void init(FilterConfig)
    컨테이너가 doFilter 실행 이전에 호출하는 메소드. web.xml에서 설정한 parameter를 인자로 받을 수 있다.

3. destroy()
    filter객체가 없어지기 전에 호출하는 메소드. doFilter에서 발생한 모든 상태(객체들..)가 사라진다.


아래는 위 ibm url에서 제공하는 예제..

package com.ibm.devworks.filters;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public final class IEFilter implements Filter {


    private FilterConfig filterConfig = null;

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
 throws IOException, ServletException {
      String browserDet = ((HttpServletRequest) request).getHeader("User-Agent").toLowerCase();

      if ( browserDet.indexOf("msie") != -1)  {
            PrintWriter out = response.getWriter();
            out.println("<html><head></head><body>");
            out.println("<h1>Sorry, page cannot be displayed!</h1>");
            out.println("</body></html>");
            out.flush();
            return;
          }


      chain.doFilter(request, response);

    }


    public void destroy() {
    }


    public void init(FilterConfig filterConfig) {
 this.filterConfig = filterConfig;

    }


}

   

,
java 2008. 9. 2. 16:42

[java]Pushlet

www.pushlet.com

stateless인 http 통신을 state 유지로 바꾸어 주기 위한 꼼수이다.

구글 웹채팅 구현 기술을 논의하다가 조현선 과장님이 생각해 내었던 아이디어인데

pushlet이란 기술로 명명되어서 많이 쓰이고 있었다.

jsp나 servlet에서 publish하지 않고 for문을 돌리는 것이다.

for문 안 쪽에는 thread.sleep(sec.)으로 실행 주기를 준다.

web서버의 session 유지 기간 설정에 의해 stateless가 되므로

client에서는 주기적으로 (보통 30분 이내) jsp나 servlet을 재호출해야 할 필요가 있다.

아래 코드를 보자


<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <meta http-equiv="Pragma" content="no-cache">
</HEAD>
<BODY BGCOLOR="blue" TEXT="white">
<%
  try {
    for (int i=1; i < 10; i++) {
       out.print("<h1>"+i+"</h1>");
       out.flush();

       try {
            Thread.sleep(3000);
       } catch (InterruptedException e) {
            out.print("<h1>"+e+"</h1>");
       }
     }
   } catch (Exception e) {
       out.print("<h1>"+e+"</h1>");
   }
   out.print("<h1>DONE</h1>");

%>
</BODY>
</HTML>



간단한 아이디어지만 효과는 놀랍다.
,
java 2008. 7. 16. 15:57

[java] ClassLoader

클래스로더라는 게 있단다. 프로그램에서 new라던지, 객체를 사용할 때 클래스를 적재하고 객체를 생생해 주는 일을 하는 것 같다. JVM이 기본적으로 부트스트랩이라는 클래스로더를 가지고 있으며 상속을 이용해 나름대로의 클래스로더를 구현할 수 있다고 한다.

아래는 j2se1.4 API doc의 ClassLoader의 내용이다.

클래스 로더는 클래스를 적재(load)하는 역할을 하는 객체이다. classloader 클래스는 추상클래스이다. 클래스의 이름을 받으면 클래스로더는 해당 클래스에 대한 정의를 구성하는 데이터를 찾거나 생산하려고 시도할 것이다. 전형적인(정해진?) 전략은 받은 이름을 파일 이름으로 바꾸고 나서 클래스의 이름에 해당하는 “class file”을 파일시스템으로부터 읽는다.

모든 클래스 객체는 자신을 정의한 ClassLoader에 대한 참조를 가지고 있다.

array 클래스의 Class객체는 class loader에 의해서 생성되지 않고 자바 런타임에 의해 요구되어질 때마다 자동적으로 생성된다. array 클래스에 Class.getClassLoader()를 실행하면 배열 요소 타입에 해당하는 클래스 로더가 리턴된다. 배열의 요소가 원시형이면 해당 배열 클래스는 클래스 로더가 없다.

응용프로그램은 자바 VM이 동적으로 클래스를 로드하는 방식을 확장하기 위한 목적으로 ClassLoader의 하위클래스를 구현한다.

클래스 로더는 보통, 보안 도메인을 지정하기 위하여 보안 관리자들에 의해 사용된다.

ClassLoader는 클래스와 자원들을 찾기 위하여 위임(delegation)모델을 사용한다. 각ClassLoader는 연관된 부모 클래스가 있다. 클래스나 자원(resource)를 찾으라는 요구를 받으면 ClassLoader 객체는 자신이 찾으려고 하기 이전에 부모 클래스 로더에 작업을 위임한다. VM에 내장된 클래스 로더 – “부트스트랩 클래스 로더(bootstrap class loader)” 는 부모 클래스로더를 가지고 있지 않으며, ClassLoader 객체의 부모로서 작업을 수행한다.

보통 자바 VM은 플랫폼 의존적인 방식으로 작동해, 로컬 파일 시스템으로부터 클래스들을 올리게 된다. 예를 들면 유닉스 시스템에서는 클래스패스 환경변수에 명시된 디렉토리로부터 클래스들을 읽어들인다.

그러나 어떤 클래스들은 파일로부터 기인하지 않는다. 네트워크와 같은 리소스로부터 발생하거나 애플리케이션에 의해 생성될 수도 있다. defileClass 메소드는 일련의 바이트 배열을 Class 클래스의 객체로 바꾸어 준다. 이렇게 새로 정의된 클래스의 객체는 Class.newInstance를 사용해서 생성할 수 있다.

클래스 로더에 의해 생성된 객체의 메소드와 생성자는 다른 클래스들을 참조할 수도 있다. 참조된 클래스(들)을 결정하기 위해서, 자바 VM은 그 클래스를 처음에 생성했던 클래스로더의 loadClass메소드를 실행한다.

예를 들어 애플리케이션은 서버로부터 클래스 파일들을 다운로드 받기 위해서 네트워크 클래스 로더를 생성할 수 있다. 아래 예제 코드를 보자.

ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();

네트워크 클래스 로더의 subclass는 네트워크로부터 클래스를 load하기 위해 findclass와 loadClassData 메소드를 정의해야 한다. 클래스를 생성하는 바이트코드를 다운로드받으면 클래스 로더는 클래스 객체를 생성하기 위해 defineClass 메소드를 사용해야 한다. 간단한 구현은 아래와 같다.

class NetworkClassLoader extends ClassLoader {
 String host;
 int port;

 public Class findClass(String name) {
     byte[] b = loadClassData(name);
     return defineClass(name, b, 0, b.length);
 }

 private byte[] loadClassData(String name) {
     // load the class data from the connection
      . . .
 }
}


정리하면,
각 클래스로더는 클래스를 찾아야 할 경우에 자신의 부모뻘 클래스로더에게 계속 작업을 위임한다. 결국 최상위 클래스로더로부터 클래스가 로딩되어 있는지 찾아 내려오고 없다면 자신이 생성하게 된다. 그러므로 모든 클래스는 한 번만 로딩되게 된다.
클래스의 객체 내부에서 다른 클래스를 찾는 경우, 그 클래스를 생성한 클래스로더가 그 클래스를 찾는다는 것...

참조 : http://crosscutter.info/tag/classloader

,
TOTAL TODAY