jakarta-taglibs-src-20060829  소스를 다운받는다.

 

custom tag 라이브러를 사용했는데, memberid를 사용했다.

<hb:usercontribinfo memberId="${param.memberid}" />

 

 

실제 자바 클래스이다.

public class UserContribListTag extends TagSupport {

           public int doStartTag() throws JspException {

                     memberId = (String) ExpressionEvaluatorManager.evaluate("memberId", memberId, String.class, this, pageContext);

 

jsp 1.0 스펙을 사용중이기 때문에 JSTL을 사용하기 위해서 ExpressionEvaluatorManager를 사용했다.

 

 ExpressionManager 클래스이다.

<ExpressionEvaluatorManager.java>

 

public static Object evaluate(String attributeName,

                                  String expression,

                                  Class expectedType,

                                  Tag tag,

                                  PageContext pageContext)

           throws JspException    {

 

        // the evaluator we'll use

        ExpressionEvaluator target = getEvaluatorByName(EVALUATOR_CLASS); // 이 부분은 문제 없음

 

        // delegate the call

        return (target.evaluate(attributeName, expression, expectedType, tag, pageContext));

    }

 

 

 

ExpressionEvaluator target = getEvaluatorByName(EVALUATOR_CLASS);

이 부분은 Target 인스턴스(ExpressionEvaluator) Evaluator 라는 클래스를 생성한다. Evaluator 는 내부적으로 static ELEvaluator 객체를 리턴하고, ELEvaluator Wrapper 클래스인데..

 

(target.evaluate(attributeName, expression, expectedType, tag, pageContext));

이때 ELEvalueator evaluator 메소드를 호출하게 된다. 다음의 코드를 죽 따라가보면 알겠지만, attributeName 파라미터로 넘겨지는 pExpressionString 아큐먼트를 쫓아가다 보면, sCachedExpressionStrings Map에 추가되는 것이 보인다.

바로 여기서도 static map이 있었다. 그래서, memberid가 계속 추가될 때마다 문제가 된 부분이었다.

 

 

<ELEvaluator.java>

static Map sCachedExpressionStrings = Collections.synchronizedMap (new HashMap ());

 

public Object evaluate (String pExpressionString, Object pContext,  Class pExpectedType, Map functions,  String defaultPrefix)  throws ELException   {

    return evaluate (pExpressionString, pContext,  pExpectedType, functions, defaultPrefix,  sLogger);

}

 

Object evaluate (String pExpressionString, Object pContext, Class pExpectedType, Map functions, String defaultPrefix, Logger pLogger)  throws ELException {

    // Check for null expression strings

    if (pExpressionString == null) {

          throw new ELException (Constants.NULL_EXPRESSION_STRING);

    }

    // Get the parsed version of the expression string

    Object parsedValue = parseExpressionString (pExpressionString);

    // Evaluate differently based on the parsed type

    if (parsedValue instanceof String) {

      // Convert the String, and cache the conversion

      String strValue = (String) parsedValue;

      return convertStaticValueToExpectedType (strValue, pExpectedType, pLogger);

    }   else if (parsedValue instanceof Expression) {

      // Evaluate the expression and convert

      Object value = ((Expression) parsedValue).evaluate (pContext, mResolver, functions, defaultPrefix, pLogger);

      return convertToExpectedType (value, pExpectedType, pLogger);

    }   else if (parsedValue instanceof ExpressionString) {

      // Evaluate the expression/string list and convert

      String strValue =

           ((ExpressionString) parsedValue).evaluate (pContext, mResolver, functions, defaultPrefix, pLogger);

      return convertToExpectedType (strValue, pExpectedType, pLogger);

    } else {

      // This should never be reached

      return null;

    }

}

 

public Object parseExpressionString (String pExpressionString)  throws ELException {

// See if it's an empty String

    if (pExpressionString.length () == 0) {

      return "";

    }

    // See if it's in the cache

    Object ret = mBypassCache ? null :  sCachedExpressionStrings.get (pExpressionString);

 

    if (ret == null) {

      // Parse the expression

      Reader r = new StringReader (pExpressionString);

      ELParser parser = new ELParser (r);

        try {

    ret = parser.ExpressionString ();

        sCachedExpressionStrings.put (pExpressionString, ret);

      } catch (ParseException exc) {

           throw new ELException (formatParseException (pExpressionString, exc));

      } catch (TokenMgrError exc) {

           throw new ELException (exc.getMessage ());

      }

    }

    return ret;

}

 

 

 

 

메모리가 계속 늘 나는 현상을 발견했는데.. 정확하게 문제를 파악하지 못한것이 흠이었다.

 

현상은 다음과 같다.

 

 

 

 

 

 

 

 

Posted by '김용환'
,