Wicket in Action

책 리뷰 2018. 6. 7. 10:55 Posted by 정직한 UnHa Kim


10년 전에 나온 Wicket 책을 이제서야 구해서 읽었다.


컴포넌트 기반 웹 프레임워크로 많은 관심을 받았는 데, 

Stateless HTTP프로토콜 위에 Stateful한 프로그래밍 모델을 구현하다보니,

세션 메모리 사용량과 확장성에서 약점이 있었던 Wicket 프레임워크.


OpenBSD pf 방화벽에서 클라이언트 접속 요청을 기억했다가 

이전과 같은 서버에 연결시켜주는 기능이 있다는 것을 알게 된 후

Wicket이 확장성에 대해서 가지던 약점도 간단하게 해결되는 듯 하고,

요즘은 메모리 가격이 저렴해서 세션 메모리 정도는 큰 문제가 안 되니,

자연스럽게 Wicket의 약점들이 다 보완 내지 해결된 듯 해서 다시 관심을 가지게 되었다.


Java와 HTML만 가지고 프로그래밍 하는 특유의 편리한 프로그래밍 모델은 그대로이고,

서버 기반 프레임워크라서 Ajax쪽은 약할 줄 알았는 데,

의외로 Ajax 기능이 상당히 괜찮다.


AjaxFallbackLink, AjaxSubmitLink를 이용하고, 

Ajax처리 결과로 업데이트 될 컴포넌트만 서버에서 지정해 주면,

Wicket이 알아서 Ajax 기능을 구현해 준다 !!


아~ 놀랍다!!~


갑자기 나도 Web 프로그래밍을 할 수 있을 것 같은 느낌이다.

그런데, Java가 너무 많이 변해서 오랜만에 Java를 접하니까 적응이 안 된다.

아직, Generic조차 낯선 데, Optional은 뭐고, Lamda함수는 또 뭔지.


10년 전 책에 나온 예제 코드가 약간의 수정만 거치면,

아직도 Wicket 최신 버전에서 돌아가는 것을 보면서,

소스코드 안정성에 대한 믿음도 생긴다.

(그 수정사항조차도 Java IDE의 기능 덕분에 크게 어렵지 않다.)


하여튼 Wicket 프레임워크 만세이다.


'책 리뷰' 카테고리의 다른 글

할 수 있다! 퀀트 투자  (0) 2019.08.28
R for Data Science  (0) 2019.07.30
월스트리트 퀀트 투자의 법칙  (0) 2019.07.27
Wicket in Action  (0) 2018.06.07
Learning DCOM  (0) 2017.08.31
파이썬으로 배우는 알고리즘 트레이딩  (0) 2017.08.24

댓글을 달아 주세요

COM 스터디 요약 정리

프로그래밍 2018. 5. 16. 13:25 Posted by 정직한 UnHa Kim

리뷰했던 DCOM 관련 서적을 읽은 내용 요약.

 

COM interface : contract regarding a provided service

IID : interface identifier. a 128-bit globally unique identifier(GUID).

IUnknown : All COM interface must be derived from. (necessary)
IUnknown.QueryInterface : the method used for 'dynamic discovery' of another interface from the object.
IUnknown.AddRef : Object reference count is incremented for management of an object's life cycle.
IUnknown.Release : Object reference count is decremented for management of an object's life cycle.

vtbl : table of function pointers. only a single vtbl exists per class. (not instance)
vptr : pointer to a vtbl (in each instance)

type library : the storage where all the type information of an object is stored
tlb : conventional separated type library file. embedded & integrated in DLL, OCX file.

IDispatch : support dynamic invocation. (optional)
dispatch interface. contains 'a dispatch identifier' (dispid) that aliases an actual method.
'dispid' also can be dynamically discovered through lookup operation.

IConnectionPoint : supports event notification. (optional)

Event : COM supports events via a concept called 'connection points' between 'source' and 'sink'(client).

Basics of COM
1. COM interface : a number of related methods
2. COM object : implements a number of interfaces, must implement 'IUnknown'
3. COM class factory : special COM object that creates or instantiates other COM objects

CLSID : class ID. Like interfaces, libraries, a COM class have unique UUID, specifically called CLSID.

HRESULT : Every COM interface method returns an HRESULT.  (32bit value composed of 4 different parts.)

1. Severity : Was the call successful? 1bit answer. 0 : success, 1 : failure
2. Reserved : 2bits that must be always 0. (Don't mess with it)
3. Facility : Who generated the error? 13bits facility code (indicating RPC, Win32, DISPATCH, etc...)
4. Code : What actually happened? 16bits return code specific to a facility

FACILITY_NULL includes a number of generic and convenient status codes.
Some of these status codes include:
- S_OK : Success
- S_FALSE : False
- E_UNEXPECTED : Unexpected, can be a catastrophic failure
- E_NOTIMPL : Method not implemented
- E_OUTOFMEMORY : Errors dealing with memory allocations
- E_NOINTERFACE : Interface not supported, used in QueryInterface
- E_POINTER : Invalid pointer
- E_FAIL : Generic error, no details available

COM supports a finite list of data types for arguments.
Base Data Types : boolean, byte, char, wchar_t, float, double, small, short, long, hyper, IUnknown*

Extended Data Types (dynamic invocation(=Automation) compatible)
- VARIANTS : a universal data type. technically a union of a bunch of special data types.
- BSTR
- SAFEARRAY

3 names for an interface
- GUID (IID_Ixxx) : uniquely identifies an interface
- class or structure name (Ixxx)
- human readable name (xxx.1)

IDispatch supports dynamic invocation but may suffer performance problem from extensive lookup.
For performance, there are other type of invocation the 'dual interface'.

Very Early Binding (vtbl binding)
Client need to be compiled with a given header file generated by MIDL.
Calls are made directly via pointers and gives maximum performance.

Early Binding (static invocation through IDispatch)
Require prior knowledge of 'dispid's.
Development tools can obtain these 'dispid's from a type library.
Since the 'dispid's are already resolved, clients don't have to call GetIDsOfNames,
which means you no longer have the performance hit of looking up 'dispid's.

Bidirectional communication.
- Client can talk to a server by calling an interface
- Server can "call back" to the client to notify them of "events" that are of interest. (Event Source)
- Implement COM object on the client side that exposes a callback interface for the server's use. (Event Sink)

Standard interfaces to support bidirectional communication through call back.
- IConnectionPointContainer
- IConnectionPoint

IConnectionPointContainer
HRESULT IConnectionPointContainer.EnumConnectionPoints([out] IEnumConnectionPoints **ppEnum)
HRESULT FindConnectionPoint([in] REFIID riid, [out] IConnectionPoint **ppCP)

- Knows about all connection points(IConnectionPoint) that the "event source" supports.
- Client can use the IConnectionPointContainer interface to ask the object whether it supports a particular connection point.
- Client also can use this interface to enumerate (via IEnumConnectionPoints) all the connection points supported by the source object.

IConnectionPoint
HRESULT GetConnectionInterface([out] IID *piid)
HRESULT GetConnectionPointContainer([out] IConnectionPointContainer **ppCPC)
HRESULT Advise([in] IUnknown *pUnkownSink, [out] DWORD *pdwCookie)
HRESULT Unadvise([in] DWORD dwCookie)
HRESULT EnumConnections([out] IEnumConnections **ppEnum)

- This interface allows a sink to call Advise to signal that it is interested in receiving callbacks.
- The connection point object is not the same object as the server COM object that implements the IConnectPointContainer interface.

Given these two standard interfaces, an event source is responsible for following:
1. Implementing the standard IConnectionPointContainer interface.
   This interface allows the sinks to enumerate or find connection points supported by the event source.
2. Implementing the standard IConnectionPoint interface for each outgoing interface.
   This is done to allow the event sink to establish a connection with the source.
   During connection, the sink sends a callback interface pointer to the source,
   so that the source can later make callbacks.
3. Calling back to the registered event sink.

An event sink is responsible for following:
1. Implementing the event sink object so that the event source can make callbacks.
2. Notifying the event source that it is interested in receiving events.
   A sink typically requests the IConnectionPointContainer interface from the event source
    and calls FindConnectionPoint to make sure that the
    event source supports the callback interface implemented by the event sink.
   This will return an IConnectionPoint interface pointer associated with the callback interface.
   A sink then uses the returned IConnectionPoint interface pointer to call Advise.
   In this method invocation, the sink sends a pointer to the its own callback interface to the event source.
   When this invocation returns, the sink will receive a registration cookie.
3. When a sink object no longer wants to receive events associated with the callback interface,
    it must notify the event source of this withdrawl by calling Unadvise using the registration cookie,
    received from calling Advise.

An event source can be thought of as a container that holds a bunch of connection point


댓글을 달아 주세요

64비트 환경에서 32비트 COM 컴포넌트 사용하기.

프로그래밍 2018. 5. 16. 13:21 Posted by 정직한 UnHa Kim
수정> 이 방식으로 COM 함수를 호출하는 것은 잘 되지만, 
        COM이 발생시키는 이벤트를 수신하고 처리하는 게 잘 안 된다.
        Xing API에서는 이러한 이벤트 처리가 필수적이어서,
        이 방안은 더 이상 사용하지 않는다.
        
----------------------------------------------        

인터넷에서 발견한 유용한 팁 번역해서 공유.

32비트 COM객체는 64비트 환경에서 사용하려고 하면, "class not registered"(등록되지 않은 클래스) 에러가 발생한다.

이 문제는 dllhost를 중간에 매개역할을 하도록 하여서 해결할 수 있다.

이를 위해서는 레지스트리 값 몇 개를 수정해야 한다.


  1. COM객체의 GUID를 'HKey_Classes_Root\Wow6432Node\CLSID\[GUID]'에서 찾아낸다.
  2. 찾아낸 후에 REG_SZ (string) 값을 추가한다. 이름은 'AppID', 값은 방금 찾아낸 COM객체 GUID이다.
  3. 'HKey_Classes_Root\Wow6432Node\AppID\' 아래에 새로운 키를 생성한다. 새로운 키의 이름은 COM객체의 GUID이다.
  4. 새로운 키 아래에 REG_SZ (string) 값을 추가한다. 이름은 'DllSurrogate', 값은 공백으로 남겨둔다.
  5. 'HKey_Local_Machine\Software\Classes\AppID\' 아래에 . 이것 또한 새로운 키는 COM객체의 GUID이어야 한다. 이 키 아래에는 새로운 값을 추가할 필요가 없다.


원문 : https://www.convert-in.com/32bit-com-64bit-system.htm


When trying to use old components and APIs, developer may face the following problem: 32bit COM objects are not usable in a 64bit environment. Attempt to access a 32bit COM in a 64bit environment will result "class not registered" error. However this issue can be resolved by using dllhost as a surrogate for the 32bit COM object.

Implementation of this fix involves a number of simple registry modifications:

  1. Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
  2. Once located add a new REG_SZ (string) value. The name must be AppID and data must be the same COM object GUID you have just searched for
  3. Add a new key under HKey_Classes_Root\Wow6432Node\AppID\ The new key must be called the same as GUID of the COM object
  4. Under the new key you've just added, add a new REG_SZ (string) value, and call it DllSurrogate. Leave the value empty.
  5. Create a new key under HKey_Local_Machine\Software\Classes\AppID\. Again the new key must be called the same as the COM object's GUID. No values are necessary to be added under this key.


댓글을 달아 주세요