jiangyubao
(jiangyubao jiangyubao)
1
备注一下,本人从07年开始一直做OSGi的应用商业开发,我整合过很多的框架,vaadin也不例外,整合成功了。其实也没那么难,掌握的技巧是classload问题。
add-on里面好像也有人做了一个整合,我看了一下,能运行起来,但我感觉不适合商用,我建议大家不要使用那个。
本人只在Equinox下测试,使用Eclipse JAVA EE作为开发环境,其他的环境理论上是可行的,但是我没有太多精力去弄。
下面就重点说说我的整合思路:
- 定制OSGiTarget,这个很关键,关系到项目成败;实际上,整合web程序最难的也就是OSGiTarget,如果论坛里有人整合不起来,本人到愿意贡献一个。
我使用的是jetty7或者jetty8,加上spring dm,过程我就不细说,反正就是到eclipse官方网站下载jetty即可。
另外,这种整合方式跟vaadin版本无关,我在vaadin6整合成功,我相信任何版本的vaadin都能成功,只要你只把它当成一个正常的web程序即可。最新版本的osgi规范(R4)是支持的。
- 明确好web程序的整合方式。从其配置来看,是每个请求都生成了一个servlet的实例,配置的是App的class对象,就意味着web程序是不能声明为osgi服务,也不能直接注入osgi服务的,只能通过ServletContext来查找osgi的服务。
差不多可以这么理解,web容器位于osgi容器之上,两者关联的唯一纽带就是ServletContext。这样做的好处就是osgi管理的bundle负责核心业务服务,web只负责对外界面,就意外着你的界面可以使用jsf、restlet+模板引起来实现。
- classload问题解决。vaadin需要加载其他bundle的class,如何实现加载任何程序的class呢?这就用到了Dynamic-Import: * 这个声明了,有了这个声明就可以动态引入任何东西。官方提供的vaadin.jar是缺少这个声明的,需要我们手工加入这个,加入方法也简单,使用rar打开,拖出到桌面,记事本修改,然后拖进去,重新压缩即可。
增加了Dynamic-Import:* 只是解决了vaadin方面的classload问题,如果加载的App没有对外export这些App的class,还是会出现ClassNotFound的问题,所以还需要我们把做的app的bundle相关classexport出去—我直接export所有class,反正也是自己用,没有任何安全问题。
要说的也就这么多,最后建议大家使用spring dm来暴露和引入osgi服务。
hailong
(hailong jiang)
2
可以共享给我一份吗, QQ575940574, 邮箱575940574@qq.com
Cloudor
(Cloudor Pool)
3
我补充一下,如果用了推送,启动atmosphere的过程中会需要扫描jar包中的类,但OSGi中的jar包
加载进URLClassLoader并非都是file://xxx的URL,因此需要对其中class文件扫描的部分进行完善。
我修改了org.atmosphere.util.annotation.AnnotationDetector类的detect方法,使其支持URL为
bundle://或platfomr://开头的URLClassLoader,否则atmosphere自带的那些filter都无法自动启动。
代码如下,我修改增加的是29到40行。
public final void detect(final String... packageNames) throws IOException
{
final String pkgNameFilter = new String[packageNames.length]
;
for (int i = 0; i < pkgNameFilter.length; ++i)
{
pkgNameFilter[i]
= packageNames[i]
.replace('.', '/');
if (!pkgNameFilter[i]
.endsWith("/"))
{
pkgNameFilter[i]
= pkgNameFilter[i]
.concat("/");
}
}
final Set<File> files = new HashSet<File>();
final Set<InputStream> streams = new HashSet<InputStream>();
for (final String packageName : pkgNameFilter)
{
final ClassLoader loader = Thread.currentThread()
.getContextClassLoader();
final Enumeration<URL> resourceEnum = loader
.getResources(packageName);
while (resourceEnum.hasMoreElements())
{
final URL url = resourceEnum.nextElement();
// Handle JBoss VFS URL's which look like (example package 'nl.dvelop'):
// vfs:/foo/bar/website.war/WEB-INF/classes/nl/dvelop/
// vfs:/foo/bar/website.war/WEB-INF/lib/dwebcore-0.0.1.jar/nl/dvelop/
// On JBoss 5.1, the protocol of VFS URL is vfsfile, make it work on JBoss 5.1
if (url.getProtocol().startsWith("bundle")
|| url.getProtocol().startsWith("platform"))
{
URL fileUrl = FileLocator.toFileURL(url);
final File dir = toFile(fileUrl);
if (dir.isDirectory())
{
files.add(dir);
if (DEBUG)
print("Add directory: '%s'", dir);
}
} else if ("file".equals(url.getProtocol())
|| "vfs".equals(url.getProtocol())
|| "vfsfile".equals(url.getProtocol()))
{
final File dir = toFile(url);
if (dir.isDirectory())
{
files.add(dir);
if (DEBUG)
print("Add directory: '%s'", dir);
}
} else if (isRunningJavaWebStart())
{
try
{
webstart((JarURLConnection) url.openConnection(),
packageName, streams);
} catch (ClassCastException cce)
{
throw new AssertionError("Not a File: "
+ url.toExternalForm());
}
} else
{
// Resource in Jar File
File jarFile;
try
{
jarFile = toFile(((JarURLConnection) url
.openConnection()).getJarFileURL());
} catch (ClassCastException cce)
{
try
{
// Weblogic crap
String u = url.toExternalForm();
if (u.startsWith("zip:"))
{
u = u.substring(4);
if (!u.startsWith("file:"))
{
u = "file:" + u;
}
u = u.substring(0, u.indexOf("!"));
}
jarFile = toFile(new URL(u));
} catch (Exception ex)
{
throw new AssertionError("Not a File: "
+ url.toExternalForm());
}
}
if (jarFile.isFile())
{
files.add(jarFile);
if (DEBUG)
print("Add jar file: '%s'", jarFile);
} else
{
throw new AssertionError("Not a File: " + jarFile);
}
}
}
}
if (!files.isEmpty())
{
detect(new ClassFileIterator(files.toArray(new File[files.size()]
),
pkgNameFilter));
} else if (!streams.isEmpty())
{
detect(new ClassFileIterator(
streams.toArray(new InputStream[streams.size()]
),
pkgNameFilter));
}
}
[/i]
[/i]
[/i]
[/i]
[/i]
oliver92
(oliver lee)
4
楼主可否将demo工程发一下,好学习一下,308637147@qq.com 谢谢