- 如何用maven创建osgi项目
- 如何启动osgi框架
- 如何在osgi外部与osgi框架通信
- 如何应用jndi配置资源引用
- 如何发布osgi服务
- 如何创建基于osgi的web应用项目
用maven的目的是使开发相率更高,而且不需要自己修改manifest.mf文件,用maven插件即可自动完成创建manifest并打包。创建这种项目的要求如下:
项目包类型为:<packaging>bundle</packaging>
要使用maven自动创建manifest.mf文件,需要插件maven-bundle-plugin,配置如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${pom.groupId}.${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${pom.name}</Bundle-Name>
<Bundle-Version>${pom.version}</Bundle-Version>
<Bundle-Activator>com.javaworld.sample.tomcat.webActivator</Bundle-Activator>
<Export-Package>com.javaworld.sample.tomcat</Export-Package>
<Import-Package>
org.osgi.framework
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
使用maven-bundle-plugin请参考:http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin ,配置好后在项目目录下执行mvn install即可
同时还要引用osgi框架支持依赖包:
<dependencies>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>framework</artifactId>
<version>3.4.2.R34x_v20080826</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
注意这里的type和scope,这种用法不仅表名bundel项目可以引用第三方bundle项目,普通项目也可以。下面将会看到。
2.启动osgi框架,并在外部与osgi框架通信
这里用Equinox OSGi框架,让EquinoxContainer 实现接口OsgiServices 并实现OsgiContainable 的start和stop方法。对于框架的启动和停止,我们放在tomcat启动和停止时触发。
首先用maven创建普通的项目,在pom中添加依赖
<dependencies>
<dependency>
<groupId>apache-tomcat</groupId>
<artifactId>catalina</artifactId>
<version>5.5.12</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>services</artifactId>
<version>3.1.200.v20071203</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>framework</artifactId>
<version>3.4.2.R34x_v20080826</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
public interface OsgiServices {
public Object getOSGiService(String serviceName);
public Class<?> getBundleClass(String bundleName, String className)
throws ClassNotFoundException;
}
//OsgiContainable 扩展OsgiServices 并提供start和stop接口
public class EquinoxContainer implements OsgiContainable {
private static Logger log = Logger
.getLogger(EquinoxContainer.class.getName());
private static BundleContext context;
private static String equinoxHome;
private static EquinoxContainer instance;
private EquinoxContainer() {
}
public static EquinoxContainer getInstance() {
if (instance == null) {
instance = new EquinoxContainer();
}
return instance;
}
public void start() throws Exception {
configFramework();
EclipseStarter.run(new String[] { "-console" }, null);
// get BundleContext
context = EclipseStarter.getSystemBundleContext();
}
private void configFramework() {
String catalinaHome = System.getProperty("catalina.home");
log.info("The catalina home is " + catalinaHome);
File filePath = new File(catalinaHome, "/osgi/equinox");
if (!filePath.exists()) {
throw new IllegalStateException(
"Can not find Equinox runtime on the specified the directory. "
+ catalinaHome + "/osgi/equinox");
}
equinoxHome = filePath.getAbsolutePath();
log.info("The osgi home is " + equinoxHome);
filePath = new File(filePath, "plugins");
String bundlePath = filePath.getAbsolutePath();
log.info("The bundle home is " + bundlePath);
// set the bundle home
FrameworkProperties.setProperty("osgi.syspath", bundlePath);
filePath = new File(equinoxHome, "configuration");
String confHome = filePath.getAbsolutePath();
// set the configuration home
FrameworkProperties.setProperty("osgi.configuration.area", confHome);
log.info("The configuration home is " + confHome);
//config.ini中至少需要配置osgi.bundles需要启动的bundles
Properties prop = loadConfigProperties(confHome, "/config.ini");
setSystemProperties(prop);
// set the framework properties
FrameworkProperties.setProperty("osgi.noShutdown", "true");
FrameworkProperties.setProperty("eclipse.ignoreApp", "true");
FrameworkProperties.setProperty("osgi.bundles.defaultStartLevel", "4");
}
。。。
}
为了让tomcat等启动时执行EquinoxContainer 的start和stop,需要实现LifecycleListener接口,并在tomcat server.xml文件中配置Listener :
<Listener className="com.javaworld.sample.tomcat.osgi.OsgiLifecycleListener" osgiType="Equinox"/>
public class OsgiLifecycleListener implements LifecycleListener {
private static Logger log = Logger.getLogger(OsgiLifecycleListener.class
.getName());
private static OsgiLifecycleListener listener;
private String osgiType = "Equinox";
private OsgiContainable osgiContent = null;
public OsgiLifecycleListener() {
}
public static OsgiLifecycleListener getInstance() {
return listener;
}
@Override
public void lifecycleEvent(LifecycleEvent event) {
try {
if (Lifecycle.INIT_EVENT.equals(event.getType())) {
log.info("Initializing osgi content. osgi type is " + osgiType);
initContent();
log.info("The osgi content initialized. osgi type is "
+ osgiType);
} else if (Lifecycle.START_EVENT.equals(event.getType())) {
log.info("Starting osgi service.");
osgiContent.start();
log.info("The osgi service started.");
} else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
log.info("Stopping osgi service.");
osgiContent.stop();
log.info("The osgi service stopped.");
}
} catch (Exception e) {
log.info(e.getMessage());
System.exit(-1);
}
}
private void initContent() throws Exception {
listener=this;
log.info("listener"+listener.toString());
osgiContent = OsgiContainerFactory.getInstance().getOsgiContent(osgiType);
}
。。。。
}
随着tomcat的启动将执行OsgiLifecycleListener,并通过OsgiLifecycleListener启动osgi框架,后者将完成bundles的安装和服务的注册等。
3。在osgi外部与osgi框架通信
OSGi通过BundleContext来获取OSGi服务,因此想在OSGi容器外获取OSGi服务,首要的问题就是要在OSGi容器外获取到BundleContext,EclipseStarter 中 提供了一个getSystemBundle- Context的方法,通过这个方法可以轻松拿到BundleContext,而通过BundleContext则可以轻易拿到OSGi服务的实例。不过 这个时候要注意的是,如果想执行这个OSGi 服务实例的方法,还是不太好做的,因为容器外的classloader和OSGi服务实例的class所在的classloader并不相同,因此不太好 按照java对象的方式直接去调用,更靠谱的是通过反射去调用。 如果想在容器外获取到OSGi容器里插件的class,一个可选的做法是通过BundleContext获取到Bundle,然后通过Bundle 来加载 class,采用这样的方法加载的class就可以保证是相同的。
public static Object getOSGiService(String serviceName) {
ServiceReference serviceRef = context.getServiceReference(serviceName);
if (serviceRef == null)
return null;
return context.getService(serviceRef);
}
public static Class<?> getBundleClass(String bundleName, String className)
throws Exception {
Bundle[] bundles = context.getBundles();
for (int i = 0; i < bundles.length; i++) {
if (bundleName.equalsIgnoreCase(bundles[i].getSymbolicName())) {
return bundles[i].loadClass(className);
}
}
return null;
}
在实现了OSGi容器外与OSGi交互之后,通常会同时产生一个需求,就是在OSGi容器内的插件要加载OSGi容器外的类,例如OSGi容器内提 供了一个mvc框架,而Action类则在OSGi容器外由其他的容器负责加载,那么这个时候就会产生这个需求了,为了做到这点,有一个比较简单的解决方 法,就是编写一个Bundle,在该Bundle中放置一个允许设置外部ClassLoader的OSGi服务,例如:
4.应用jndi配置资源引用
上面知道要在osgi外面引用osgi服务或者osgi类,唯一可行的办法是获取BundleContext,这点是可以在osgi框架获取,这样一来BundleContext就是我们与osgi通信的桥梁了,OsgiServices 也是通过此桥梁与osgi框架通信,为方便对OsgiServices 的获取,现在将OsgiServices配置到jndi。同样把Resource添加到server.xml的Host标签中:
<Resource name="osgi/services" auth="Container"
type="com.javaworld.sample.tomcat.osgi.OsgiServices"
factory="com.javaworld.sample.tomcat.osgi.OsgiServicesObjectFactory" />
在tomcat 的web.xml中添加Resource引用:
<resource-env-ref>
<description>osgi services</description>
<resource-env-ref-name>osgi/services</resource-env-ref-name>
<resource-env-ref-type>
com.javaworld.sample.tomcat.osgi.OsgiServices
</resource-env-ref-type>
</resource-env-ref>
public class OsgiServicesObjectFactory implements ObjectFactory {
private static Logger log = Logger.getLogger(OsgiServicesObjectFactory.class
.getName());
private OsgiServices osgiServices;
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?, ?> environment) throws Exception {
Map<String, String> attMap = new HashMap<String, String>();
// Customize the bean properties from our attributes
Reference ref = (Reference) obj;
Enumeration<RefAddr> addrs = ref.getAll();
while (addrs.hasMoreElements()) {
RefAddr addr = addrs.nextElement();
String attrName = addr.getType();
String value = (String) addr.getContent();
log.info("the attribute is (" + attrName + " == " + value + ")");
attMap.put(attrName, value);
}
log.info("getObjectInstance called.");
osgiServices=OsgiLifecycleListener.getInstance().getOsgiServices();
return osgiServices;
}
}
5. 发布osgi服务
public interface HelloService {
public String sayHello();
}
public class webActivator implements BundleActivator {
ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) {
serviceRegistration = bundleContext.registerService(
HelloService.class.getName(), new HelloServiceImpl(),
new Properties());
}
public void stop(BundleContext bundleContext) {
serviceRegistration.unregister();
}
}
6.创建基于osgi的web应用项目
创建<packaging>war</packaging>web项目,添以下类:
public class TomcatWebCall {
public static String invokeService() {
try {
HelloService service = OsgiServiceFactory.getOsgiService(
"osgi/services", HelloService.class);
return service.sayHello();
} catch (IllegalArgumentException e) {
e.printStackTrace();
e.printStackTrace();
}
return null;
}
}
public class OsgiServiceFactory {
public static <T> T getOsgiService(String jndiName,Class<T> clazz) {
OsgiServices services = (OsgiServices) Utils.lookup(jndiName);
OsgiServiceInvocationHandler handler = new OsgiServiceInvocationHandler(
services, clazz.getName());
return Utils.getProxyObject(clazz,handler);
}
public class OsgiServiceInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
Object service = services.getOSGiService(servicName);
if (service == null) {
throw new IllegalServiceException("Cann't find out osgi service:"
+ servicName);
}
Method[] methods = service.getClass().getDeclaredMethods();
for (Method meth : methods) {
if (meth.getName().equals(method.getName())) {
return meth.invoke(service, args);
}
}
。。。
}
}
}
public class Utils {
private static final String CONTAINER_PREFIX = "java:comp/env/";
public static <T> T getProxyObject(Class<T> clazz, InvocationHandler handler) {
Object o = Proxy.newProxyInstance(clazz.getClassLoader(),
new Class[] { clazz }, handler);
return clazz.cast(o);
}
private static String convertJndiName(String jndiName) {
if (!jndiName.startsWith(CONTAINER_PREFIX)
&& jndiName.indexOf(':') == -1) {
jndiName = CONTAINER_PREFIX + jndiName;
}
return jndiName;
}
public static Object lookup(String jndiName) {
String convertedName = convertJndiName(jndiName);
Object jndiObject = null;
try {
Context context = new InitialContext();
jndiObject = context.lookup(convertedName);
} catch (NamingException e) {
throw new IllegalServiceException(
"The JNDI OSGi services name is error.", e);
} catch (Exception e) {
throw new IllegalServiceException(
"The JNDI OSGi services can not be initialized.", e);
}
return jndiObject;
}
}
简单的jsp测试:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="com.javaworld.sample.tomcat.TomcatWebCall"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Demo invoke HelloService</title>
</head>
<body>
<%=TomcatWebCall.invokeService() %>
</body>
</html>
项目包类型为:<packaging>bundle</packaging>
要使用maven自动创建manifest.mf文件,需要插件maven-bundle-plugin,配置如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${pom.groupId}.${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${pom.name}</Bundle-Name>
<Bundle-Version>${pom.version}</Bundle-Version>
<Bundle-Activator>com.javaworld.sample.tomcat.webActivator</Bundle-Activator>
<Export-Package>com.javaworld.sample.tomcat</Export-Package>
<Import-Package>
org.osgi.framework
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
使用maven-bundle-plugin请参考:http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin ,配置好后在项目目录下执行mvn install即可
同时还要引用osgi框架支持依赖包:
<dependencies>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>framework</artifactId>
<version>3.4.2.R34x_v20080826</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
注意这里的type和scope,这种用法不仅表名bundel项目可以引用第三方bundle项目,普通项目也可以。下面将会看到。
2.启动osgi框架,并在外部与osgi框架通信
这里用Equinox OSGi框架,让EquinoxContainer 实现接口OsgiServices 并实现OsgiContainable 的start和stop方法。对于框架的启动和停止,我们放在tomcat启动和停止时触发。
首先用maven创建普通的项目,在pom中添加依赖
<dependencies>
<dependency>
<groupId>apache-tomcat</groupId>
<artifactId>catalina</artifactId>
<version>5.5.12</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>services</artifactId>
<version>3.1.200.v20071203</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>framework</artifactId>
<version>3.4.2.R34x_v20080826</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
public interface OsgiServices {
public Object getOSGiService(String serviceName);
public Class<?> getBundleClass(String bundleName, String className)
throws ClassNotFoundException;
}
//OsgiContainable 扩展OsgiServices 并提供start和stop接口
public class EquinoxContainer implements OsgiContainable {
private static Logger log = Logger
.getLogger(EquinoxContainer.class.getName());
private static BundleContext context;
private static String equinoxHome;
private static EquinoxContainer instance;
private EquinoxContainer() {
}
public static EquinoxContainer getInstance() {
if (instance == null) {
instance = new EquinoxContainer();
}
return instance;
}
public void start() throws Exception {
configFramework();
EclipseStarter.run(new String[] { "-console" }, null);
// get BundleContext
context = EclipseStarter.getSystemBundleContext();
}
private void configFramework() {
String catalinaHome = System.getProperty("catalina.home");
log.info("The catalina home is " + catalinaHome);
File filePath = new File(catalinaHome, "/osgi/equinox");
if (!filePath.exists()) {
throw new IllegalStateException(
"Can not find Equinox runtime on the specified the directory. "
+ catalinaHome + "/osgi/equinox");
}
equinoxHome = filePath.getAbsolutePath();
log.info("The osgi home is " + equinoxHome);
filePath = new File(filePath, "plugins");
String bundlePath = filePath.getAbsolutePath();
log.info("The bundle home is " + bundlePath);
// set the bundle home
FrameworkProperties.setProperty("osgi.syspath", bundlePath);
filePath = new File(equinoxHome, "configuration");
String confHome = filePath.getAbsolutePath();
// set the configuration home
FrameworkProperties.setProperty("osgi.configuration.area", confHome);
log.info("The configuration home is " + confHome);
//config.ini中至少需要配置osgi.bundles需要启动的bundles
Properties prop = loadConfigProperties(confHome, "/config.ini");
setSystemProperties(prop);
// set the framework properties
FrameworkProperties.setProperty("osgi.noShutdown", "true");
FrameworkProperties.setProperty("eclipse.ignoreApp", "true");
FrameworkProperties.setProperty("osgi.bundles.defaultStartLevel", "4");
}
。。。
}
为了让tomcat等启动时执行EquinoxContainer 的start和stop,需要实现LifecycleListener接口,并在tomcat server.xml文件中配置Listener :
<Listener className="com.javaworld.sample.tomcat.osgi.OsgiLifecycleListener" osgiType="Equinox"/>
public class OsgiLifecycleListener implements LifecycleListener {
private static Logger log = Logger.getLogger(OsgiLifecycleListener.class
.getName());
private static OsgiLifecycleListener listener;
private String osgiType = "Equinox";
private OsgiContainable osgiContent = null;
public OsgiLifecycleListener() {
}
public static OsgiLifecycleListener getInstance() {
return listener;
}
@Override
public void lifecycleEvent(LifecycleEvent event) {
try {
if (Lifecycle.INIT_EVENT.equals(event.getType())) {
log.info("Initializing osgi content. osgi type is " + osgiType);
initContent();
log.info("The osgi content initialized. osgi type is "
+ osgiType);
} else if (Lifecycle.START_EVENT.equals(event.getType())) {
log.info("Starting osgi service.");
osgiContent.start();
log.info("The osgi service started.");
} else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
log.info("Stopping osgi service.");
osgiContent.stop();
log.info("The osgi service stopped.");
}
} catch (Exception e) {
log.info(e.getMessage());
System.exit(-1);
}
}
private void initContent() throws Exception {
listener=this;
log.info("listener"+listener.toString());
osgiContent = OsgiContainerFactory.getInstance().getOsgiContent(osgiType);
}
。。。。
}
随着tomcat的启动将执行OsgiLifecycleListener,并通过OsgiLifecycleListener启动osgi框架,后者将完成bundles的安装和服务的注册等。
3。在osgi外部与osgi框架通信
OSGi通过BundleContext来获取OSGi服务,因此想在OSGi容器外获取OSGi服务,首要的问题就是要在OSGi容器外获取到BundleContext,EclipseStarter 中 提供了一个getSystemBundle- Context的方法,通过这个方法可以轻松拿到BundleContext,而通过BundleContext则可以轻易拿到OSGi服务的实例。不过 这个时候要注意的是,如果想执行这个OSGi 服务实例的方法,还是不太好做的,因为容器外的classloader和OSGi服务实例的class所在的classloader并不相同,因此不太好 按照java对象的方式直接去调用,更靠谱的是通过反射去调用。 如果想在容器外获取到OSGi容器里插件的class,一个可选的做法是通过BundleContext获取到Bundle,然后通过Bundle 来加载 class,采用这样的方法加载的class就可以保证是相同的。
public static Object getOSGiService(String serviceName) {
ServiceReference serviceRef = context.getServiceReference(serviceName);
if (serviceRef == null)
return null;
return context.getService(serviceRef);
}
public static Class<?> getBundleClass(String bundleName, String className)
throws Exception {
Bundle[] bundles = context.getBundles();
for (int i = 0; i < bundles.length; i++) {
if (bundleName.equalsIgnoreCase(bundles[i].getSymbolicName())) {
return bundles[i].loadClass(className);
}
}
return null;
}
在实现了OSGi容器外与OSGi交互之后,通常会同时产生一个需求,就是在OSGi容器内的插件要加载OSGi容器外的类,例如OSGi容器内提 供了一个mvc框架,而Action类则在OSGi容器外由其他的容器负责加载,那么这个时候就会产生这个需求了,为了做到这点,有一个比较简单的解决方 法,就是编写一个Bundle,在该Bundle中放置一个允许设置外部ClassLoader的OSGi服务,例如:
Java代码
- public class ClassLoaderService{
- public void setClassLoader(ClassLoader classloader);
- }
基于上面的方法,在外部启动Equinox 的类中去反射执行ClassLoaderService这个OSGi服务的setClassLoader方法,将外部的classloader设置进来, 然后在OSGi容器的插件中要加载OSGi容器外的类的时候就调用下面这个ClassLoaderService去完成类的加载。
4.应用jndi配置资源引用
上面知道要在osgi外面引用osgi服务或者osgi类,唯一可行的办法是获取BundleContext,这点是可以在osgi框架获取,这样一来BundleContext就是我们与osgi通信的桥梁了,OsgiServices 也是通过此桥梁与osgi框架通信,为方便对OsgiServices 的获取,现在将OsgiServices配置到jndi。同样把Resource添加到server.xml的Host标签中:
<Resource name="osgi/services" auth="Container"
type="com.javaworld.sample.tomcat.osgi.OsgiServices"
factory="com.javaworld.sample.tomcat.osgi.OsgiServicesObjectFactory" />
在tomcat 的web.xml中添加Resource引用:
<resource-env-ref>
<description>osgi services</description>
<resource-env-ref-name>osgi/services</resource-env-ref-name>
<resource-env-ref-type>
com.javaworld.sample.tomcat.osgi.OsgiServices
</resource-env-ref-type>
</resource-env-ref>
public class OsgiServicesObjectFactory implements ObjectFactory {
private static Logger log = Logger.getLogger(OsgiServicesObjectFactory.class
.getName());
private OsgiServices osgiServices;
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?, ?> environment) throws Exception {
Map<String, String> attMap = new HashMap<String, String>();
// Customize the bean properties from our attributes
Reference ref = (Reference) obj;
Enumeration<RefAddr> addrs = ref.getAll();
while (addrs.hasMoreElements()) {
RefAddr addr = addrs.nextElement();
String attrName = addr.getType();
String value = (String) addr.getContent();
log.info("the attribute is (" + attrName + " == " + value + ")");
attMap.put(attrName, value);
}
log.info("getObjectInstance called.");
osgiServices=OsgiLifecycleListener.getInstance().getOsgiServices();
return osgiServices;
}
}
5. 发布osgi服务
public interface HelloService {
public String sayHello();
}
public class webActivator implements BundleActivator {
ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) {
serviceRegistration = bundleContext.registerService(
HelloService.class.getName(), new HelloServiceImpl(),
new Properties());
}
public void stop(BundleContext bundleContext) {
serviceRegistration.unregister();
}
}
6.创建基于osgi的web应用项目
创建<packaging>war</packaging>web项目,添以下类:
public class TomcatWebCall {
public static String invokeService() {
try {
HelloService service = OsgiServiceFactory.getOsgiService(
"osgi/services", HelloService.class);
return service.sayHello();
} catch (IllegalArgumentException e) {
e.printStackTrace();
e.printStackTrace();
}
return null;
}
}
public class OsgiServiceFactory {
public static <T> T getOsgiService(String jndiName,Class<T> clazz) {
OsgiServices services = (OsgiServices) Utils.lookup(jndiName);
OsgiServiceInvocationHandler handler = new OsgiServiceInvocationHandler(
services, clazz.getName());
return Utils.getProxyObject(clazz,handler);
}
public class OsgiServiceInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
Object service = services.getOSGiService(servicName);
if (service == null) {
throw new IllegalServiceException("Cann't find out osgi service:"
+ servicName);
}
Method[] methods = service.getClass().getDeclaredMethods();
for (Method meth : methods) {
if (meth.getName().equals(method.getName())) {
return meth.invoke(service, args);
}
}
。。。
}
}
}
public class Utils {
private static final String CONTAINER_PREFIX = "java:comp/env/";
public static <T> T getProxyObject(Class<T> clazz, InvocationHandler handler) {
Object o = Proxy.newProxyInstance(clazz.getClassLoader(),
new Class[] { clazz }, handler);
return clazz.cast(o);
}
private static String convertJndiName(String jndiName) {
if (!jndiName.startsWith(CONTAINER_PREFIX)
&& jndiName.indexOf(':') == -1) {
jndiName = CONTAINER_PREFIX + jndiName;
}
return jndiName;
}
public static Object lookup(String jndiName) {
String convertedName = convertJndiName(jndiName);
Object jndiObject = null;
try {
Context context = new InitialContext();
jndiObject = context.lookup(convertedName);
} catch (NamingException e) {
throw new IllegalServiceException(
"The JNDI OSGi services name is error.", e);
} catch (Exception e) {
throw new IllegalServiceException(
"The JNDI OSGi services can not be initialized.", e);
}
return jndiObject;
}
}
简单的jsp测试:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="com.javaworld.sample.tomcat.TomcatWebCall"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Demo invoke HelloService</title>
</head>
<body>
<%=TomcatWebCall.invokeService() %>
</body>
</html>
相关推荐
OSGI(Open Services Gateway Initiative)是一种开放标准,用于创建可模块化的Java应用程序。它提供了一种灵活的框架,使得开发者可以构建、部署和管理模块化组件,这些组件被称为服务或bundle。OSGI的核心理念是将...
OSGI(Open Services Gateway Initiative)是一种模块化系统和Java服务框架,它允许应用程序由一系列可独立更新和替换的模块组成,这些模块称为“bundle”。在本实例中,我们将探讨如何利用OSGI技术来开发Eclipse...
OSGi(Open Services Gateway Initiative)学习笔记(一) 在IT领域,OSGi是一种模块化系统和Java服务平台,它提供了一种动态管理软件组件的能力。本文将深入探讨OSGi的基本概念、架构以及如何使用它来构建可扩展和...
赠送jar包:osgi-resource-locator-1.0.1.jar; 赠送原API文档:osgi-resource-locator-1.0.1-javadoc.jar; 赠送源代码:osgi-resource-locator-1.0.1-sources.jar; 赠送Maven依赖信息文件:osgi-resource-locator...
OSGi(Open Services Gateway Initiative)是一种模块化系统和Java服务框架,它允许在单个JVM上运行多个版本的相同库或服务,从而解决了不同版本jar包冲突的问题。本示例通过一个名为“myself”的工程,展示了如何...
赠送jar包:osgi-resource-locator-1.0.1.jar; 赠送原API文档:osgi-resource-locator-1.0.1-javadoc.jar; 赠送源代码:osgi-resource-locator-1.0.1-sources.jar; 赠送Maven依赖信息文件:osgi-resource-locator...
《深入理解OSGi:以org.eclipse.osgi_3.7.0.v20110613及其源码为例》 OSGi(Open Services Gateway Initiative)是一种Java模块化系统,它为开发人员提供了动态模块化的解决方案,使得Java应用程序能够更好地管理和...
OSGi(Open Services Gateway Initiative)是一个由OSGi联盟(OSGi Alliance)维护和发展的开放性规范,它定义了如何在Java平台的基础上实现模块化编程和服务动态化。OSGi规范使得Java程序可以被设计成一套小型的、...
OSGi(Open Services Gateway Initiative)是一种Java平台上的模块化服务框架,它定义了一种标准,使得开发者能够构建可互操作的、动态的、模块化的软件系统。OSGi的核心概念是基于Java的模块化,它的主要目标是为...
OSGi(Open Services Gateway Initiative)是一种Java模块化系统,它为开发人员提供了一种动态、模块化的运行时环境。在OSGi中,应用程序被分解为称为“bundle”的独立单元,这些bundle可以相互依赖并独立地加载、...
OSGI(Open Services Gateway Initiative)是一种模块化系统和Java服务框架,它允许应用程序以模块化的方式构建,每个模块称为一个Bundle。在这个案例中,我们将探讨如何整合OSGI、Spring、Mybatis以及Spring MVC来...
这个压缩包包含了关于OSGI的重要文档,分别是“OSGi R4核心规范文档”、“OSGi服务文档”以及“OSGi-最佳原理与实践”(王昊编著)。下面将详细介绍这些文档所涵盖的关键知识点。 首先,"OSGi R4核心规范文档"是...
《企业OSGi实战》一书是OSGi企业应用的权威指南,它不仅涵盖了OSGi在企业环境中的应用,还提供了Java企业版(Java EE)与OSGi特性的融合方法。本书详细介绍了模块化编程的重要性,以及OSGi如何强化Java的模块化能力...
标题 "org.osgi.core-4.2.0" 指的是一个特定版本的 OSGi(Open Services Gateway Initiative)核心框架库,版本号为 4.2.0。OSGi 是一个 Java 平台的模块化系统和服务平台,它提供了一种标准的方式来组织和管理 Java...
OSGi规范中文版是一本全面介绍OSGi技术的书籍,它不仅涵盖了OSGi技术的基础知识,还详细介绍了OSGi的内部结构和工作原理,对于想要深入学习和应用OSGi技术的开发者而言,是一本非常有价值的参考书。 ### OSGi规范的...
OSGi(Open Services Gateway Initiative)是一种开放标准,用于创建模块化Java应用程序。它提供了一种动态的、可扩展的框架,使得开发人员可以构建、部署和管理软件组件。本资源包含两本书籍:“OSGi原理与最佳实践...
OSGI组件编程是一种在Java平台上构建模块化应用程序的方法,它由OSGi联盟制定标准,并被广泛应用于企业级软件开发,尤其是对于需要高度可扩展性和动态性的系统。在本教程中,我们将深入探讨如何使用Eclipse和Equinox...
标题:osgi规范r4 描述与标签:osgi规范 知识点详解: 1. **OSGi Service Platform**:OSGi(Open Services Gateway Initiative)服务平台是用于构建动态、模块化Java应用程序的一种框架。它允许在运行时安装、...
OSGI(Open Services Gateway Initiative)是一种开放标准,用于创建模块化和动态的Java应用程序。它为Java开发人员提供了一个框架,使他们能够构建可热插拔的组件,从而实现更灵活、可扩展和可维护的软件系统。在本...