그동안 써왔던. blog.naver.com/knight76 에서 knight76.tistory.com으로 이사하다.

이사하는 방법은 의외로 쉽다.

아래 페이지(감사한 개발자~)에서 실행프로그램을 다운받아서 XML로 파일로 만들도록 한다.
http://endlessprogramming.tistory.com/200

그리고, 티스토리에서. 관리메뉴를 이용한다.
환경설정-> 데이터 관리 -> 데이터 복원 메뉴를 이용하여 xml을 include한다.


'Trend' 카테고리의 다른 글

오라클 썬 인수  (0) 2009.04.21
이클립스 사용자에 대한 통계  (0) 2009.04.08
졸트 어워드 상 수상작 발표  (0) 2009.03.25
Hezekiah Walker - Faithful Is Our God  (1) 2009.03.24
구글 안드로이드의 전략  (0) 2009.03.18
Posted by '김용환'
,

JMX상에서 POJO를 Standard MBean 또는 MXBean으로 만드는 법

 출처 : 
http://blogs.sun.com/jmxetc/entry/dynamicmbeans,_modelmbeans,_and_pojos...



The JMX forum on SDN is a lively place. Recently, Athahar was trying to expose a POJO resource through JMX - and quite naturally, decided to try out doing this with a ModelMBean. However, ModelMBeans are not the only way to this - and here are a few thoughts, which borrow heavily on some of Eamonn's most recent blog entries.

Turning your POJO into a Standard MBean or an MXBean

This is the traditional way of exposing resources using the JMX API: have the Java Object you want to expose implement an interface which groups all the attributes (getters and setters) and operations (methods) you want to expose for management.

If you are using JDK 6, then tag this interface as MXBean
If you are using earlier versions of the JDK, then name this interface by appending "MBean" to your object's java class name - or wrap your object in a StandardMBean
Then at runtime, register your object(s) in the (platformMBeanServer.

The platform MBeanServer is the MBeanServer that is used by the JVM default Management Agent, so if you register your MBeans in there, you will be able to see them directly when connecting JConsole to the default JVM agent.

This is the easiest way to proceed, and often the best way. Having an interface makes it possible to create MBean proxies, and to code remote clients against that interface. Using MXBean ensure that remote clients which do not have access to your interface/classes will still be able to interact with your MBeans. The MBean (or MXBean) interface makes it also possible to separate those method that are suited for remote invocation from those that should only be called locally, from your application.

However, there can be some cases where such a method is not possible. For instance, if the interface of your MBean is not known at compile time (rare but possible), or if the object you want to manage is a third party object, obtained e.g. from a legacy application whose source code cannot be modified. In those cases, you may want to turn to the other methods listed below.

Using a Model MBean

Model MBeans were designed to dynamically map some java object resource to a JMX Model specified at runtime. In theory, Model MBeans could be a perfect match for what we are attempting to do here. In practice, you might find that Model MBeans with their very powerful list of configurable features are a bit of an over kill. But should you wish to create and configure a Model MBean to expose your Java resource, here is an example of code that creates a trivial Model MBean to exposes all getter, setters, and operations of a simple POJO. The method makeModelMBean(Object resource) shown below introspect the given resource in order to configure aRequiredModelMBean that will expose that resource. This code example outline a few details which may not be intuitive:

  1. All getters and setters must also be declared as operations.
  2. When creating a ModelMBeanAttributeInfo object you need to explicitely specify, for that attribute, the names of the getter and setter methods in the Descriptor, even when you pass those methods to the attribute info constructor.

    


    public static ModelMBean makeModelMBean(Object resource)
    throws JMException, InvalidTargetObjectTypeException {
        
        final Method[] methods = resource.getClass().getMethods();
        
        final List<Method> operations = new ArrayList<Method>();
        final List<Method> getters = new ArrayList<Method>();
        final Map<String,Method> setters = new LinkedHashMap<String,Method>();
        
        for (Method method : methods) {
            // don't want to expose getClass(), hashCode(), equals(), etc...
            if (method.getDeclaringClass().equals(Object.class)) continue;
            
            if (method.getName().startsWith("get") &&
                    !method.getName().equals("get") &&
                    !method.getName().equals("getClass") &&
                    method.getParameterTypes().length == 0 &&
                    method.getReturnType() != void.class) {
                getters.add(method);
            } 
            if (method.getName().startsWith("set") &&
                    !method.getName().equals("set") &&
                    method.getParameterTypes().length == 1 &&
                    method.getReturnType().equals(void.class)) {
                setters.put(method.getName(),method);
            }

            operations.add(method);
        }
        
        
        final List<ModelMBeanAttributeInfo> attrinfo = 
                new ArrayList<ModelMBeanAttributeInfo>();

        for (Method getter:getters) {            
            
            final String attrName = getter.getName().substring(3);
            final String setterMethod = "set"+attrName ; // construct setter method
            
            // Check whether there's a setter and if so removes it from the
            // setter's map.
            //
            Method setter = setters.remove(setterMethod);
            
            if (setter != null) {
                // If there's a setter, it must have the same "type" than 
                // the getter
                if (!getter.getReturnType().equals(
                        setter.getParameterTypes()[0])) {
                    System.err.println("Warning: setter "+setter.getName()+
                            " doesn't have the expected type: setter ignored.");
                    setter = null;
                }
            }
            
            attrinfo.add( makeAttribute(getter,setter));
        }
             
        // check if there are setters for which there was no getter
        //
        for (Method setter:setters.values()) {
            // It would be unusual to have a setter with no getter! 
            System.err.println("Warning: setter "+setter.getName()+
                    " has no corresponding getter!");
            attrinfo.add( makeAttribute(null,setter));
        }
        
        final ModelMBeanAttributeInfo[] attrs =
            attrinfo.toArray(new ModelMBeanAttributeInfo[attrinfo.size()]);
        
        final int opcount = operations.size();
        final ModelMBeanOperationInfo[] ops = 
                new ModelMBeanOperationInfo[opcount];
        for (int i=0;i<opcount;i++){
            final Method m = operations.get(i);
            ops[i] = new ModelMBeanOperationInfo(m.getName(),m);
        }
        
        
        ModelMBeanInfo mmbi =
                new ModelMBeanInfoSupport(resource.getClass().getName(),
                resource.getClass().getName(),
                attrs,
                null,  // constructors
                ops,
                null); // notifications
        ModelMBean mmb = new RequiredModelMBean(mmbi);
        mmb.setManagedResource(resource, "ObjectReference");
        return mmb;
    }

    private static ModelMBeanAttributeInfo makeAttribute(Method getter,
                                                         Method setter)
                                 throws IntrospectionException {
        final String attrName;
        if (getter != null)
            attrName = getter.getName().substring(3);
        else 
            attrName = setter.getName().substring(3);

        final List<String> descriptors = new ArrayList<String>();
        descriptors.add("name=" + attrName);
        descriptors.add("descriptorType=attribute");
        if (getter!=null) {
           descriptors.add("getMethod=" + getter.getName());
        }
        if (setter!=null) {
           descriptors.add("setMethod=" + setter.getName());
        }

        final Descriptor attrD = new DescriptorSupport(
                descriptors.toArray(new String[descriptors.size()]));
       
        return new ModelMBeanAttributeInfo(attrName, attrName, getter, setter,
                attrD);
    }

To test my Model MBean, I have created a dummy resource POJO, wrapped it in a Model MBean, and registered it in the platform MBeanServer.

    
    public static class MyPojo {
        private String foo = "foo!";
        private long weird = -1;
        private Object bad = new Long(0);
        
        // RW attribute
        public String getFoo() {return foo;}
        public void setFoo(String foo) {this.foo=foo;}
        
        // RO attribute
        public int getBar() {return 1;}
        
        // WO attribute (weird)
        public void setWeird(long weird) {this.weird=weird;}
        
        // Bad attribute: doesn't respect JavaBean patterns...
        public Object getBad() {return bad;}
        
        public void setBad(Number bad) {this.bad = bad;}
        
        // just an operation!
        public long doIt() {
            System.out.println("doIt!");
            return weird+1;
        }
    }
    
    public static void main(String[] args) throws Exception {
        
        final MyPojo obj = new MyPojo();
        final ModelMBean mbean = makeModelMBean(obj);
        ManagementFactory.getPlatformMBeanServer().
                registerMBean(mbean,new ObjectName("test:type=MyPojo"));
        System.out.println("Connect now with JConsole.");
        System.out.println("Strike <Return> to exit.");
        System.in.read();
    }

Here is how it appears in JConsole:

Using a Dynamic MBean

A lighter solution might be to write a DynamicMBean that will introspect the class of your resource object. Here is the code of aDynamicPOJOMBean that does exactly that. If your resource can emit some notifications, then you could modify this DynamicPOJOMBean to extend NotificationBroadcasterSupport - and arrange to call sendNotification() when a Notification needs to be sent, or code aDynamicPOJOEmitterMBean that extends DynamicPOJOMBean and implements NotificationEmitter, and delegates notification handling to a wrappedNotificationBroadcasterSupport object (see the Advanced JMX Example for JDK 6 for a discussion of these two notifications patterns).

The code required for our DynamicPOJOMBean is quite simple:

    
public class DynamicPOJOMBean implements DynamicMBean {
    
    /**
     * A logger for this class.
     **/
    private static final Logger LOG =
            Logger.getLogger(DynamicPOJOMBean.class.getName());
    
    final Map<String,Method> getters;
    final Map<String,Method> setters;
    final Set<Method> operations;
    final Object resource;
    final MBeanInfo info;
        
    /** Creates a new instance of DynamicPOJOMBean */
    public DynamicPOJOMBean(Object obj) {
        getters = new LinkedHashMap<String,Method>();
        setters = new LinkedHashMap<String,Method>();
        operations = new LinkedHashSet<Method>();
        resource = obj;
        try {
            info = initialize();
        } catch (IntrospectionException ex) {
            throw new IllegalArgumentException(obj.getClass().getName(),ex);
        }
    }
    private MBeanInfo initialize() throws IntrospectionException {
        final List<MBeanAttributeInfo> attributesInfo = 
                new ArrayList<MBeanAttributeInfo>();
        final List<MBeanOperationInfo> operationsInfo = 
                new ArrayList<MBeanOperationInfo>();
        final Set<String> attributesName = new HashSet<String>();
        final ArrayList<Method> ops = new ArrayList<Method>();
        for (Method m:resource.getClass().getMethods()) {
            if (m.getDeclaringClass().equals(Object.class)) continue;
            if (m.getName().startsWith("get") &&
                    !m.getName().equals("get") &&
                    !m.getName().equals("getClass") &&
                    m.getParameterTypes().length == 0 &&
                    m.getReturnType() != void.class) {
                getters.put(m.getName().substring(3),m);
            } else if (m.getName().startsWith("is") &&
                    !m.getName().equals("is") &&
                    m.getParameterTypes().length == 0 &&
                    m.getReturnType() == boolean.class) {
                getters.put(m.getName().substring(2),m);
            } else if (m.getName().startsWith("set") &&
                    !m.getName().equals("set") &&
                    m.getParameterTypes().length == 1 &&
                    m.getReturnType().equals(void.class)) {
                setters.put(m.getName().substring(3),m);
            } else {
                ops.add(m);
            }
        }
        
        attributesName.addAll(getters.keySet());
        attributesName.addAll(setters.keySet());
        
        for (String attrName : attributesName) {
            final Method get = getters.get(attrName);
            Method set = setters.get(attrName);
            if (get != null && set != null && 
                get.getReturnType() != set.getParameterTypes()[0]) {
                set = null;
                ops.add(setters.remove(attrName));
            }
            final MBeanAttributeInfo mbi = 
                    getAttributeInfo(attrName,get,set);
            if (mbi == null && get != null) {
                ops.add(getters.remove(attrName));
            }
            if (mbi == null && set != null) {
                ops.add(setters.remove(attrName));
            }
            if (mbi != null) attributesInfo.add(mbi);
        }
        
        for (Method m:ops) {
            final MBeanOperationInfo opi = getOperationInfo(m);
            if (opi == null) continue;
            operations.add(m);
            operationsInfo.add(opi);
        }
        return getMBeanInfo(resource,attributesInfo.
                toArray(new MBeanAttributeInfo[attributesInfo.size()]),
                operationsInfo.
                toArray(new MBeanOperationInfo[operationsInfo.size()]));
    }

    protected MBeanAttributeInfo getAttributeInfo(String attrName, 
            Method get, Method set) throws IntrospectionException {
        return new MBeanAttributeInfo(attrName,attrName,get,set);
    }

    protected MBeanOperationInfo getOperationInfo(Method m) {
        if (m.getDeclaringClass()==Object.class) return null;
        return new MBeanOperationInfo(m.getName(),m);
    }

    protected MBeanInfo getMBeanInfo(Object resource, 
            MBeanAttributeInfo[] attrs, MBeanOperationInfo[] ops) {
        return new MBeanInfo(resource.getClass().getName(),
                resource.getClass().getName(),attrs,null,ops,null);
    }

    public Object getAttribute(String attribute) 
        throws AttributeNotFoundException, MBeanException, ReflectionException {
        final Method get = getters.get(attribute);
        if (get == null) throw new AttributeNotFoundException(attribute);
        try {
            return get.invoke(resource);
        } catch (IllegalArgumentException ex) {
            throw new ReflectionException(ex);
        } catch (InvocationTargetException ex) {
            final Throwable cause = ex.getCause();
            if (cause instanceof Exception) 
                throw new MBeanException((Exception)cause);
            throw new RuntimeErrorException((Error)cause);
        } catch (IllegalAccessException ex) {
            throw new ReflectionException(ex);
        }
    }

    public void setAttribute(Attribute attribute) 
        throws AttributeNotFoundException, InvalidAttributeValueException, 
            MBeanException, ReflectionException {
        final Method set = setters.get(attribute);
        if (set == null) 
            throw new AttributeNotFoundException(attribute.getName());
        try {
            set.invoke(resource,attribute.getValue());
        } catch (IllegalArgumentException ex) {
            throw new ReflectionException(ex);
        } catch (InvocationTargetException ex) {
            final Throwable cause = ex.getCause();
            if (cause instanceof Exception) 
                throw new MBeanException((Exception)cause);
            throw new RuntimeErrorException((Error)cause);
        } catch (IllegalAccessException ex) {
            throw new ReflectionException(ex);
        }
    }

    public AttributeList getAttributes(String[] attributes) {
        if (attributes == null) return new AttributeList();
        final List<Attribute> result = 
                new ArrayList<Attribute>(attributes.length);
        for (String attr : attributes) {
            final Method get = getters.get(attr);
            try {
                result.add(new Attribute(attr,get.invoke(resource)));
            } catch (Exception x) {
                continue;
            }
        }
        return new AttributeList(result);
    }

    public AttributeList setAttributes(AttributeList attributes) {
        if (attributes == null) return new AttributeList();
        final List<Attribute> result = 
                new ArrayList<Attribute>(attributes.size());
        for (Object item : attributes) {
            final Attribute attr = (Attribute)item;
	    final String name = attr.getName();
            final Method set = setters.get(name);
            try {
		set.invoke(resource,attr.getValue());
		final Method get = getters.get(name);
                final Object newval = 
		    (get==null)?attr.getValue():get.invoke(resource);
                result.add(new Attribute(name,newval));
            } catch (Exception x) {
                continue;
            }
        }
        return new AttributeList(result);
    }

    public Object invoke(String actionName, Object[] params, String[] signature) 
        throws MBeanException, ReflectionException {
        Method toInvoke = null;
        if (params == null) params = new Object[0];
        if (signature == null) signature = new String[0];
        for (Method m : operations) {
            if (!m.getName().equals(actionName)) continue;
            final Class[] sig = m.getParameterTypes();
            if (sig.length == params.length) {
                if (sig.length == 0) toInvoke=m;
                else if (signature.length == sig.length) {
                    toInvoke = m;
                    for (int i=0;i<sig.length;i++) {
                        if (!sig[i].getName().equals(signature[i])) {
                            toInvoke = null; 
                            break;
                        }
                    }
                }
            }
            if (toInvoke != null) break;
        }
        if (toInvoke == null) 
            throw new ReflectionException(new NoSuchMethodException(actionName));
        try {
            return toInvoke.invoke(resource,params);
        } catch (IllegalArgumentException ex) {
            throw new ReflectionException(ex);
        } catch (InvocationTargetException ex) {
            final Throwable cause = ex.getCause();
            if (cause instanceof Exception) 
                throw new MBeanException((Exception)cause);
            throw new RuntimeErrorException((Error)cause);
        } catch (IllegalAccessException ex) {
            throw new ReflectionException(ex);
        }
    }

    public MBeanInfo getMBeanInfo() {
        return info;
    }
  
}

I have tested this DynamicPOJOMBean with the same dummy resource that I used for my ModelMBean above. Here is a JConsole window that shows both MBeans: "test:type=MyPojo,name=Model" is the previously coded ModelMBean, "test:type=MyPojo,name=dynamic" is my lighter DynamicMBean version...

Wrapping your POJO inside an MXBean Proxy

The drawback of the two methods described above is when your POJO use custom classes (other POJOs) as input/output to its getter/setter and/or operations. In that case - if you use a plain MBean to expose your POJO, you will need to:

  1. make sure that those custom classes are serializable
  2. distribute the jars containing those classes to the clients that monitor your POJO.

In that case, using an MXBean would be the best answer. We have already discussed how to turn your POJO into an MXBean, in the first section of this blog. However, this implies that you can modify the source code of your object, and make it implement an MXBean interface.

An alternative to that would be to wrap your POJO inside a java.lang.reflect.Proxy that would implement the appropriate MXBean interface. This is one of the use cases described by Eamonn in one of his recent blog entries. Here are the steps that would be required:

  1. You would need to write an MXBean interface containing all the getters, setters, and methods you want to expose.
  2. You would need to write an InvocationHandler, which when invoked on a method m defined in 1), finds out the method with the same name and signature on your object, and invokes it. The code of the InvocationHandler below is extracted from Eamon's blog: Build Your Own Interface
    The MBeanInvocationHandler used in the constructed Proxy looks like this: 
    public class MBeanInvocationHandler implements InvocationHandler {
        public MBeanInvocationHandler(Object wrapped) {
            this.wrapped = wrapped;
        }
    
        public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
            Class wrappedClass = wrapped.getClass();
            Method methodInWrapped =
                wrappedClass.getMethod(method.getName(), method.getParameterTypes());
            try {
                return methodInWrapped.invoke(wrapped, args);
            } catch (InvocationTargetException e) {
                throw e.getCause();
            }
        }
        
        private final Object wrapped;
    }
    
  3. Using this invocation handler, you would be able to create a Proxy implementing your MXBean interface created in 1) and forward all its methods to the wrapped Plain Old Java Object.

Provided that the name of the interface you provide ends with "MXBean", the proxy obtained will implement that MXBean interface, and is therefore itself an MXBean, that you can directly register in an MBeanServer.

Of course, in this case, you still need to write an MXBean interface for your POJO, but your POJO no longer needs to implement it - it simply needs to have the "same" methods than those defined in the interface. The code required for the InvocationHandler is completely generic, and is driven by introspection of the provided interface. If your reason for not turning your POJO into an MBean was simply that you couldn't change its codebase, then statically writing an MXBean interface for creating an MXBean proxy (or statically generating that interface by introspecting your POJO class) might be enough to suit your needs.

Using dynamic code generation

This latter case is a use case that exactly corresponds to what is described by Eamonn in his blog about generating interfaces. Instead of statically writing (or generating) the interface needed to create the MXBean Proxy for your POJO, you could dynamically generate it at runtime.

Before you start generating code however, make really sure that none of the previously described methods can be used!

Waiting for JMX 2.0?

One of the RFE considered for JMX 2.0 is Annotations to simplify MBean development. This could come in the form of e.g. @Managedannotations as suggested in Eamonn's Blog. Having such annotation would not solve our original problem, which was to expose a resource whose source code cannot be changed, but it could simplify the development of MBean wrappers, such as those discussed in this entry.

What? What time is it? So late? When I started writing this entry, I thought it would take me ten minutes! I had only these two small classes that I wanted to share! Sorry to have been so long, now I need to run!

Cheers,
-- daniel

See also: javax.management.StandardMBean: When and Why. 
Look also for other JMX related articles in this blog...
Tags:     
Posted by dfuchs ( Nov 22 2006, 09:01:43 PM CET ) Permalink Comments [3]

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

중요한 DBCP 설정 공부  (0) 2009.04.10
Jad 사용법  (0) 2009.04.10
jdk 5,6 클래스를 jdk 3,4에서 실행하기  (0) 2009.03.30
JMX에서의 Internalization  (0) 2009.03.25
toString 구현을 쉽게 구현하기  (0) 2009.03.25
Posted by '김용환'
,
오라클에는 사실 생각없이 살던 나에게 Preparedstatement 이슈는 큰 충격이었다. 이번기회에 오라클을 설치할 줄이야. 사실 난 oca 9i다. 3과목만 패쓰한 상태인데.. 왜 이렇게 오라클을 모르지??  ㅋㅋ

'DB' 카테고리의 다른 글

오라클 메가진  (0) 2009.04.09
오라클의 Soft parsing, Hard pasring  (2) 2009.03.26
오라클 성능과 관련된 V$SYSSTAT 테이블  (0) 2009.03.26
오라클 DB Wait Event 관련  (0) 2009.02.19
오라클 - DB crash  (0) 2008.11.13
Posted by '김용환'
,
http://with72.com/

'Economics' 카테고리의 다른 글

다우-AIG WTI 선물 지수 보기.  (0) 2009.04.09
BDI 지수 보기  (0) 2009.04.09
가장 높은 이자로 주는 통장 소개 (2009.3.19일 기준)  (0) 2009.03.19
미국 은행 CDS 현황(2009.3)  (0) 2009.03.12
Domino Theory - Economics  (0) 2009.03.11
Posted by '김용환'
,
JMX 스펙리더의 글을 퍼온다.
Posted by '김용환'
,
jmx를 이용하여 해당 jvm instance의 cpu usage를 측정하는 메소드는 다음과 같이 되어 있다.

private void _getJavaRuntime() {
OperatingSystemMXBean osbean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
RuntimeMXBean runbean = (RuntimeMXBean) ManagementFactory.getRuntimeMXBean();

long bfprocesstime = osbean.getProcessCpuTime();
long bfuptime = runbean.getUptime();
long ncpus = osbean.getAvailableProcessors();

for (int i = 0; i < 1000000; ++i) {
ncpus = osbean.getAvailableProcessors();
}

long afprocesstime = osbean.getProcessCpuTime();
long afuptime = runbean.getUptime();

float cal = (afprocesstime - bfprocesstime)
/ ((afuptime - bfuptime) * 10000f);

javacpu = Math.min(99f, cal);
uptime = runbean.getUptime(); 
}

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

JDK7에 clossloader의 close 메소드가 생기다니.  (0) 2009.04.09
JMX 에서 standardbean 사용 관련 Tip  (0) 2009.03.28
Java Memory 이야기  (0) 2009.03.25
svn과 연동 (svnkit)  (0) 2009.03.25
exception시 어떻게 되는가?  (0) 2009.03.05
Posted by '김용환'
,

일일빌드 시스템을 만들고 나서, 어느 정도 시간을 지내고 나서, 이 시스템의 장점이 무엇인가 생각해보았다. 200여개나 되는 프로젝트를 관리를 기준으로 생각한 것이다.

 

장점

 

1. 소스의 검증

2. 소스의 검색 용이

   공통 모듈을 쓸 때, 이게 어디서 쓰는지, 참조하기가 어렵거나 잘못된 자바 스크립트나 자바 소스를 찾아낼 수 있다는 점이 아주 훌륭하다. 소스 검색은 역시 acl!!

3. 한번에 소스 commit이 용이

  200여개나 되는 프로젝트에서 특정 패턴에 맞는 DB 설정에 대해서 수정을 하려고 할 때, 담당자들에게 일일히 연락하지 않고, 직접 수정이 가능하다.

4. 소스 복잡도 측정 가능

 

단점

1. 서버의 사용률이 좀 적다.

서버를 여기저기 함께 사용해야 하나 싶다.

 

 

사실 허드슨과 같이 좋은 툴들이 있어서 과연 일일빌드 시스템이 의미가 있겠냐마는..

사실은 내가 원하는 형태로 구현가능하고, 일일빌드 시스템의 의미에 대해서 생각해 볼 필요는 있는 것 같다.

 

 

 

Posted by '김용환'
,
Faithful is our God 이란 곡을 처음 들었을 때 얼마나 짜릿했는지~~~ 휴~


Faithful, faithful, faithful is our God
Faithful, faithful, faithful is our God
Faithful, faithful, faithful is our God
Faithful, faithful, faithful is our God
I'm reaing the harvest God promised me
Take back what the devil stole from me
And I rejoice today, for I shall recover it all
Yes, I rejoice today, for I shall rocover it all

Holy, holy, holy is our God
Holy, holy, holy is our God
Holy, holy, holy is our God
Holy, holy, holy is our God
I'm reaing the harvest God promised me
Take back what the devil stole from me
And I rejoice today, for I shall recover it all
Yes, I rejoice today, for I shall rocover it all

Jesus, Jesus, Jesus is our God
Jesus, Jesus, Jesus is our God
Jesus, Jesus, Jesus is our God
Jesus, Jesus, Jesus is our God
I'm reaing the harvest God promised me
Take back what the devil stole from me(12x)

And I rejoice today (8x)
For I shall recover it all

'Trend' 카테고리의 다른 글

티스토리로 이사하기  (0) 2009.04.01
졸트 어워드 상 수상작 발표  (0) 2009.03.25
구글 안드로이드의 전략  (0) 2009.03.18
Podcasting 공부 싸이트  (0) 2009.03.09
Spring Batch 예제 - 2009년..  (0) 2009.03.05
Posted by '김용환'
,

어느날 Transport 클래스의 send 메소드를 사용하는데, 영원히 기다리는 현상이 발견되었다.

이는 메일서버가 약간 이상해지거나. 잘못된 주소로 계속 retry하는 시도가 있으면, 마치 block되는 느낌으로 계속 있는 현상이 발생된다.

 

확인을 해보니.. Tranport 클래스의 send 메소드는 block 형 메소드였다.

 

http://forums.sun.com/thread.jspa?forumID=43&threadID=474662

 

 

자세한 내용을 확인하기 위해서 API를 살펴보았다.

http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html

 

mail.smtp.connectiontimeout int Socket connection timeout value in milliseconds. Default is infinite timeout.
mail.smtp.timeout int Socket I/O timeout value in milliseconds. Default is infinite timeout.

 

 

대충 사용법은 다음과 같다..

 

 

 

  Properties props = System.getProperties();
  props.put("mail.smtp.host", conf.get("mail/smtp/host"));
  props.put("mail.debug", conf.get("mail/debug"));
  props.put("mail.transport.protocol", "smtp");
  props.put("mail.smtp.connectiontimeout", "5000");
  props.put("mail.smtp.timeout", "5000");  

 

Session session = Session.getInstance(props);

MimeMessage message = new MimeMessage(session);

message.setFrom(ia);
  
  message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
  message.setSubject(subject, encoding);
  message.setContent(text, "text/html; charset=" + encoding);

  Transport.send(message);

 

 

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

JMX에서의 Internalization  (0) 2009.03.25
toString 구현을 쉽게 구현하기  (0) 2009.03.25
sping 2.0 aop @aspect 사용 예제  (0) 2009.03.06
Hadoop 사용 예제  (0) 2009.03.04
Hadoop 설치 하기  (0) 2009.03.04
Posted by '김용환'
,

제일은행 두드림 통장 4.1 % (지금 가입한 상태임. CMA보다 좋아보임.)

 

아껴서 잘 사세~

 

출처 :

http://clien.career.co.kr/zboard/view.php?id=use&page=1&sn1=&divpage=2&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=10606

 


우선 제일은행의 두드림통장을 소개해드리면 첫째 제일은행 본은행과 함께 타은행(우체국, 농협포함)에서 영업시간외에 자동화기기에서 예금을 인출해도 수수료가 없다는 것입니다. 물론 인터넷뱅킹과 텔레뱅킹, 휴대폰 타은행 이체 역시 수수료가 없습니다. 이율은 세전 30일동안은 0.1% 30일이후는 연리 4.1%로 타계좌에비해 높은 이율을 자랑합니다.

단점은 제일은행이 지점이 별로 없어 입금하기가 좀 어렵다는것이 있겠네요
그리고 타은행 영업시간외 예금인출의 수수료 무료는 올해말까지로 계획되어 있지만 상황에따라 연장할수 있다고도 하니 참고바람니다.

자세한것은 홈페이지 참조(금융상품몰 => 금융/신탁 =>입출금자유 =>두드림통장을 클릭하세요^^)
http://www.scfirstbank.com/



다음은 국민은행 스타트 통장입니다.
이상품은 두드림에 비하면 해택받기가좀 까다롭습니다.

아래 홈페이지 참조하시기 바람니다.
금융상품몰 => 예금/골드뱅킹 => 예금상품안내 => 입출금이 자유로운예금 => KB Star*t 통장 클릭하세요^^

http://money.kbstar.com/quics?asfilecode=5023&_nextPage=page=B000029&weblog=introAb1

홈폐이지에 없는 내용을 설명드리자면 가입후 만 35세까지만 혜택을 받을수있고 그 이후는 일반통장으로 자동전환됩니다.

저같은 경우 단기자금은 지점이 많아 입금이 쉬운 국민은행에 100만원이하의 쓸돈만 남기고 제일은행에 계좌이체를 합니다. 두드림은 30일이후 연리4%이기 때문이지요^^ 영업시간후 국민은행이 안보일땐 두드림 계좌에서 인출하기도 하구요^^

두 예금모두 4%대의 높은 금리를 보장하면서 입출금이 자유로우니 아무쪼록 잘 활용하시기 바람니다.

이상 어려운시대에 조금이나마 절약하시는데 도움이 되었으면 합니다. ㄳ

'Economics' 카테고리의 다른 글

BDI 지수 보기  (0) 2009.04.09
경제 및 주식 관련 링크 모음 사이트  (0) 2009.03.25
미국 은행 CDS 현황(2009.3)  (0) 2009.03.12
Domino Theory - Economics  (0) 2009.03.11
무디스 발표 잠재파산기업 명단 공개  (0) 2009.03.11
Posted by '김용환'
,