2011年9月19日 星期一

OSGi : Web Application for Wicket 1.5, Spring 3.0.5, Spring Security and JPA 1.0/2.0 with EclipseLink 2.x

從我的Blog tag OSGi(SpringDM) 可以看到舊的一些文章, 舊的OSGi Web Application 是基於Wicket 1.4.17, 因為Wicket 1.5 Release 的版本跟1.4.17有一些改變, 所以在OSGI 環境裡面也會有一些改變,本篇主要是針對如何Upgrade Wicket 1.4.17 to 1.5.0

如果有需要的話可以在我的github 找到 1.4.17 版本的Project source
Link here 1.4.17
而1.5.0 版本的Project Source 在這邊
Link here 1.5.0

在舊的1.4.17 的版本裡,從Wicket 官網download 下來後的檔案就包含了OSGI 版本的MANIFEST.mf檔, 可以直接放到Virgo下的ext/usr 裡面使用,但是在1.5.0 放上去會產生一些問題, 下面是Wicket 1.5.0 的jar檔

wicket-auth-roles-1.5.0.jar
wicket-core-1.5.0.jar
wicket-datetime-1.5.0.jar
wicket-devutils-1.5.0.jar
wicket-extensions-1.5.0.jar
wicket-guice-1.5.0.jar
wicket-ioc-1.5.0.jar
wicket-jmx-1.5.0.jar
wicket-objectsizeof-agent-1.5.0.jar
wicket-request-1.5.0.jar
wicket-spring-1.5.0.jar
wicket-util-1.5.0.jar
wicket-velocity-1.5.0.jar
當你deploy 到Virgo server 上時, 在Server Console 輸入 vsh package list 可以看到如下的 package list:

....
...
org.apache.request
org.apache.request
....
....

然後在Web Application 執行時就會出現ClassNotFoundException , 這是因為Export org.apache.request package 的有2個bundle , wicket-core-1.5.0.jar 跟 wicket-request-1.5.0.jar, 可以參考 Wicket forum , Wicket 1.5 and OSGi 的討論,
因為OSGI 針對相同package 的部份會以先install 的bundle 優先為準, 解決辦法之一就是將這些相同Export Package 的bundle 合成一個bundle , 在這邊我是把wicket-util-1.5.0.jar , wicket-request-1.5.0.jar 2個bundle 合到wicket-core-1.5.0.jar 裡面去

在wicket 1.5.0 download 的檔案包含了source code , 將他import 進來(using maven import) , project 如下 :

然後這邊我把wicket-request and wicket-util 的source code 完整的copy 到wicket-core裡面,compiler 完後把MANIFEST.mf檔做些修正,如下
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: 1.5.0_22 (Sun Microsystems Inc.)
Built-By: igor
Build-Jdk: 1.5.0_22
Specification-Title: Wicket Core
Specification-Version: 1.5.0
Specification-Vendor: Apache Software Foundation
Implementation-Title: Wicket Core
Implementation-Version: 1.5.0
Implementation-Vendor-Id: org.apache.wicket
Implementation-Vendor: Apache Software Foundation
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Import-Package: org.apache.wicket,
 org.apache.wicket.request.flow,
 org.apache.wicket.request.http,
 org.apache.wicket.request.http.handler,
 org.apache.wicket.request.mapper.info,
 org.apache.wicket.request.mapper.mount,
 org.apache.wicket.request.mapper.parameter,
 org.apache.wicket.serialize,
 org.apache.wicket.util,
 org.apache.wicket.util.collections,
 org.apache.wicket.util.convert,
 org.apache.wicket.util.convert.converter,
 org.apache.wicket.util.diff,
 org.apache.wicket.util.listener,
 org.apache.wicket.util.lang,
 org.apache.wicket.util.string,
 org.apache.wicket.util.parse.metapattern,
 org.apache.wicket.util.parse.metapattern.parsers,
 org.apache.wicket.util.time,
 org.apache.wicket.util.upload,
 org.apache.wicket.util.value,
 org.apache.wicket.util.visit,
 org.apache.wicket.util.watch
Bnd-LastModified: 1314977204960
Export-Package: org.apache.wicket,
 org.apache.wicket.ajax,
 org.apache.wicket.ajax.calldecorator,
 org.apache.wicket.ajax.form,
 org.apache.wicket.ajax.markup.html,
 org.apache.wicket.ajax.markup.html.form,
 org.apache.wicket.ajax.markup.html.navigation.paging,
 org.apache.wicket.application,
 org.apache.wicket.authentication,
 org.apache.wicket.authentication.strategy,
 org.apache.wicket.authorization,
 org.apache.wicket.authorization.strategies,
 org.apache.wicket.authorization.strategies.action,
 org.apache.wicket.authorization.strategies.page,
 org.apache.wicket.behavior,
 org.apache.wicket.css,
 org.apache.wicket.event,
 org.apache.wicket.feedback,
 org.apache.wicket.javascript,
 org.apache.wicket.markup,
 org.apache.wicket.markup.html,
 org.apache.wicket.markup.html.basic,
 org.apache.wicket.markup.html.border,
 org.apache.wicket.markup.html.debug,
 org.apache.wicket.markup.html.form,
 org.apache.wicket.markup.html.form.upload,
 org.apache.wicket.markup.html.form.validation,
 org.apache.wicket.markup.html.image,
 org.apache.wicket.markup.html.image.resource,
 org.apache.wicket.markup.html.include,
 org.apache.wicket.markup.html.internal,
 org.apache.wicket.markup.html.link,
 org.apache.wicket.markup.html.list,
 org.apache.wicket.markup.html.navigation.paging,
 org.apache.wicket.markup.html.pages,
 org.apache.wicket.markup.html.panel,
 org.apache.wicket.markup.html.tree,
 org.apache.wicket.markup.html.tree.res,
 org.apache.wicket.markup.loader,
 org.apache.wicket.markup.parser,
 org.apache.wicket.markup.parser.filter,
 org.apache.wicket.markup.renderStrategy,
 org.apache.wicket.markup.repeater,
 org.apache.wicket.markup.repeater.data,
 org.apache.wicket.markup.repeater.util,
 org.apache.wicket.markup.resolver,
 org.apache.wicket.markup.transformer,
 org.apache.wicket.mock,
 org.apache.wicket.model,
 org.apache.wicket.model.util,
 org.apache.wicket.page,
 org.apache.wicket.pageStore,
 org.apache.wicket.pageStore.memory,
 org.apache.wicket.protocol.http,
 org.apache.wicket.protocol.http.documentvalidation,
 org.apache.wicket.protocol.http.mock,
 org.apache.wicket.protocol.http.request,
 org.apache.wicket.protocol.http.servlet,
 org.apache.wicket.protocol.https,
 org.apache.wicket.request,
 org.apache.wicket.request.component,
 org.apache.wicket.request.cycle,
 org.apache.wicket.request.flow,
 org.apache.wicket.request.http,
 org.apache.wicket.request.http.flow,
 org.apache.wicket.request.http.handler,
 org.apache.wicket.request.handler,
 org.apache.wicket.request.handler.render,
 org.apache.wicket.request.handler.resource,
 org.apache.wicket.request.mapper,
 org.apache.wicket.request.mapper.info,
 org.apache.wicket.request.mapper.mount,
 org.apache.wicket.request.mapper.parameter,
 org.apache.wicket.request.parameter,
 org.apache.wicket.request.resource,
 org.apache.wicket.request.resource.caching,
 org.apache.wicket.request.resource.caching.version,
 org.apache.wicket.resource,
 org.apache.wicket.resource.aggregation,
 org.apache.wicket.resource.dependencies,
 org.apache.wicket.resource.filtering,
 org.apache.wicket.resource.loader,
 org.apache.wicket.response,
 org.apache.wicket.response.filter,
 org.apache.wicket.serialize,
 org.apache.wicket.serialize.java,
 org.apache.wicket.session,
 org.apache.wicket.settings,
 org.apache.wicket.settings.def,
 org.apache.wicket.util,
 org.apache.wicket.util.cookies,
 org.apache.wicket.util.collections,
 org.apache.wicket.util.convert,
 org.apache.wicket.util.convert.converter,
 org.apache.wicket.util.crypt,
 org.apache.wicket.util.diff,
 org.apache.wicket.util.diff.myers,
 org.apache.wicket.util.file,
 org.apache.wicket.util.io,
 org.apache.wicket.util.iterator,
 org.apache.wicket.util.lang,
 org.apache.wicket.util.listener,
 org.apache.wicket.util.parse.metapattern,
 org.apache.wicket.util.parse.metapattern.parsers,
 org.apache.wicket.util.resource,
 org.apache.wicket.util.resource.locator,
 org.apache.wicket.util.resource.locator.caching,
 org.apache.wicket.util.string,
 org.apache.wicket.util.string.interpolator,
 org.apache.wicket.util.thread,
 org.apache.wicket.util.time,
 org.apache.wicket.util.template,
 org.apache.wicket.util.tester,
 org.apache.wicket.util.upload,
 org.apache.wicket.util.value,
 org.apache.wicket.util.visit,
 org.apache.wicket.util.watch,
 org.apache.wicket.util.xml,
 org.apache.wicket.validation,
 org.apache.wicket.validation.validator 
Bundle-Version: 1.5.0
Bundle-Name: Wicket Core
Bundle-Description: Wicket is a Java web application framework that ta
 kes simplicity,   separation of concerns and ease of development to a
  whole new level.   Wicket pages can be mocked up, previewed and late
 r revised using   standard WYSIWYG HTML design tools. Dynamic content
  processing and   form handling is all handled in Java code using a f
 irst-class   component model backed by POJO data beans that can easil
 y be   persisted using your favorite technology.
Bundle-DocURL: http://apache.org
Bundle-Vendor: Apache Software Foundation
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.apache.wicket.core
Tool: Bnd-1.15.0
DynamicImport-Package: *

這邊做的是將wicket-util ,wicket-request裡面的MANIFEST.mf檔的information merg到wicket-core裡面, 針對Improt-package & export-package的部份,3個 bundle的MANIFEST.mf檔能在 jar檔裡面找到, 完成後要從新build 或著是 package都行.

再來就是針對Wicket 1.5 的部份做修改, ClassLoader 跟@springbean , @ijnect 的部份可以參考Wicket Stuff裡面的osgi project , wicket-osgi-parent ,
原本1.4.17 的WebAuthenticatedWebSession 的部份使用@Ijnect ,injectDependencies()裡面的改動如下
InjectorHolder.getInjector().inject(this); 
↓
Injector.get() .inject(this),

雖然在WicketApplication裡面設定了OsgiComponentInjector , 但是在WebAuthenticatedWebSession 裡面還是會取不到inject instance, 解決的辦法是使用@Springbean, 而WicketApplication跟1.4.17 版本不同的地方如下
protected void init() {
   logger.info("WicketApplication init........");
   logger.info("osgiClassResolver = "  osgiClassResolver);
//     this.getPageSettings().addComponentResolver(new OsgiExtensionPointResolver(this.bundleCtx));
     super.init(); 
    
    
     this.getApplicationSettings().setClassResolver(osgiClassResolver);
     this.getResourceSettings().setResourceStreamLocator(new OsgiResourceStreamLocator());
     OsgiComponentInjector compInj = new OsgiComponentInjector(true);
     getComponentInstantiationListeners().add(new SpringComponentInjector(this));
     getComponentInstantiationListeners().add(compInj);
     getMarkupSettings().setDefaultMarkupEncoding(DEFAULT_ENCODING);

 }
在1.5 版本裡面 getComponentInstantiationListeners() 裡面已經改成使用Lst 去存取,
private final List<T> listeners = new CopyOnWriteArrayList<T>();
在這邊就把SpringComponentInjector and OsgiComponentInjector 2個都加到listeners 裡面, 然後在
WebAuthenticatedWebSession 需要AuthenticationManager的部份就使用@SpringBean(name="authenticationManager") 來Inject , 而其他的wicket page 就使用@Inject 來取的OSGi Service

Reference :

Wicket Stuff
Wicket Forum: Wicket 1.5 and OSGi