Spring、OSGi和SpringSource应用平台是Java生态系统中的重要组成部分,它们各自扮演着不同的角色,但也可以协同工作以提供强大而灵活的应用程序开发环境。
-
Spring:Spring是一个开源的Java应用框架,它提供了全面的基础设施支持,旨在简化企业级应用的开发。Spring的核心特性包括依赖注入(DI)和面向切面编程(AOP),这些特性帮助开发者管理组件之间的依赖关系,并分离业务逻辑与横切关注点(如日志记录、事务管理等)。
-
OSGi:OSGi(Open Service Gateway initiative)是一个动态模块系统,用于Java。它允许应用程序在运行时加载、更新和卸载模块,而无需重新启动整个应用。OSGi定义了一套标准服务接口,使得不同的模块可以相互通信。这种模块化和动态性使得OSGi特别适合构建可扩展且易于维护的大型系统。
-
SpringSource Application Platform:SpringSource应用平台是基于Spring框架的一个集成平台,它结合了Spring的强大功能和OSGi的动态模块能力。该平台提供了一个统一的环境,用于开发、部署和管理基于Spring的应用。通过使用SpringSource,开发者可以利用OSGi的动态模块特性来构建更加灵活和可维护的应用程序。
总结来说,Spring提供了一种轻量级的容器解决方案,用于简化企业级应用的开发;OSGi则提供了一个动态模块系统,允许在运行时对应用进行模块化管理;而SpringSource应用平台则是这两者的结合体,为开发者提供了一个强大的工具集,用于创建高性能、可扩展的企业级应用。
OSGi(动态模块系统)是一种面向Java的动态模块系统,它允许应用程序以模块化的方式开发和部署。在OSGi中,模块被称为“bundles”,这些bundles可以动态地加载和卸载,而无需停止整个应用程序。
实现模块动态加载和卸载的关键机制:
-
Bundle生命周期管理:
每个OSGi bundle都有一个生命周期,包括安装、启动、停止、更新和卸载等状态。通过调用相应的API方法,可以在运行时控制bundle的状态。例如,BundleContext
接口提供了installBundle()
,startBundle()
,stopBundle()
,updateBundle()
, 和uninstallBundle()
等方法来管理bundle的生命周期。 -
类加载器隔离:
OSGi使用独立的类加载器为每个bundle加载类,从而实现模块之间的隔离。这种隔离确保了一个bundle中的类不会干扰另一个bundle中的类,除非显式声明依赖关系。这种设计使得bundle可以在不影响其他部分的情况下进行更新或替换。 -
服务导向架构:
OSGi定义了一套服务框架,允许bundle之间通过发布和消费服务进行通信。一个bundle可以注册服务供其他bundle使用,也可以查找并使用其他bundle提供的服务。这种松耦合的设计增强了系统的灵活性和可扩展性。 -
动态包导入:
bundle可以通过动态包导入机制在运行时导入所需的包。这意味着bundle不需要在编译时确定所有的依赖关系,而是可以在运行时根据需要动态添加或移除依赖项。 -
版本管理和兼容性:
OSGi支持包的版本管理,确保不同版本的bundle能够正确地共存和交互。这有助于处理向后兼容性问题,并允许开发者逐步迁移到新的API版本。 -
安全沙箱:
OSGi提供了一个安全框架,允许为不同的bundle设置不同的权限和访问控制策略。这有助于保护系统免受恶意代码的影响,并确保只有受信任的bundle才能执行敏感操作。 -
模块化配置:
bundle可以通过配置文件(如MANIFEST.MF文件)声明其元数据,包括依赖关系、导出的包和服务等。这些信息用于在安装和启动时解析和验证bundle的兼容性。 -
热插拔支持:
OSGi框架支持热插拔功能,即在不重启应用程序的情况下添加或删除bundle。这通常通过监听文件系统的变化来实现,一旦检测到新的bundle被添加到指定的目录中,框架会自动安装并启动该bundle。 -
事件监听和钩子:
OSGi提供了丰富的事件监听器和钩子机制,允许开发者在bundle生命周期的各个阶段插入自定义逻辑。例如,可以在bundle启动前进行初始化检查,或者在bundle停止后进行清理工作。 -
调试和监控工具:
OSGi生态系统提供了多种调试和监控工具,帮助开发者跟踪bundle的状态变化、性能指标以及潜在的问题。这些工具对于维护大型OSGi应用程序至关重要。
** Updated May 2nd with case study :- see the bottom of this post for details **
I’m sure most of you reading this blog will have seen the announcement of the SpringSource Application Platform yesterday. If not, be sure to check out Rob’s blog post which describes some of the motivation, programming model, and roadmap.
A couple of common questions are being asked that I’d like to address straight away in this post. After that I’ll describe two other exciting announcements that complement the SpringSource Application Platform itself but that didn’t grab the headlines yesterday: the SpringSource Enterprise Bundle Repository and the Application Platform tools for Eclipse. Together these complete the story around OSGi-based enterprise application development with Spring.
The question I’ve heard several times over the last 24 hours is: what’s wrong with OSGi - why can’t we just use a vanilla OSGi Service Platform (such as Equinox, Felix, or Knopflerfish) instead of the SpringSource Application Platform?
There is absolutely nothing wrong with OSGi.
OSGi is a great foundation and service platform - that’s why we and many others have chosen to build upon it. It’s proven in a wide range of industries and applications, and underpins applications such as Eclipse and IBM’s WebSphere as well as the middleware stacks of several other vendors.
Programming straight to the the OSGi specification APIs lacks some of the qualities we have come to expect for enterprise applications - such as the ability to use dependency injection and create applications that are easily unit and integration testable outside of the container. Programming straight to the OSGi specification APIs also forces you to deal at a relatively low level with the dynamics of the OSGi platform - what do you do when modules and services you depend on are stopped, started, installed, and updated at runtime? But there’s no fundamental obstacle here that we weren’t able to overcome with the Spring Dynamic Modules project. Applications built using Spring Dynamic Modules can run on any standard OSGi Service Platform, and we test all our builds against Equinox, Felix, and Knopflerfish. We are committed to ensuring that Spring Dynamic Modules and the Spring based programming model remain runtime neutral. That position will not change with the introduction of the SpringSource Application Platform.
There is also absolutely nothing wrong with existing enterprise libraries.
Well, ok. There are some cases that leave a little to be desired, but by and large we know how to make them work for enterprise application development needs.
So what’s the problem then?
If OSGi works so well, and existing enterprise libraries are meeting our needs, then where’s the problem? The difficulty comes when you try to combine an OSGi Service Platform with a set of existing enterprise libraries that weren’t written with OSGi in mind. That’s not the fault of OSGi, it’s got a great model that provides for excellent modularity, versioning, and operational control. It’s not the fault of the enterprise libraries either - they weren’t written to run under OSGi. But the very things that make OSGi so attractive break assumptions that the developers of those enterprise libraries made. The modularity model of OSGi for example stops you seeing the private parts of other people’s bundles. That’s exactly what you want, until you realise that your enterprise library can no longer see your application types. Lots of things can break: from commons logging to jsps, tag libraries to data sources, load-time weaving to component scanning, resource loading to orm mapping. The list goes on… (Yes, you can get many of these things to work when you package your application code and all of the libraries it needs into a single bundle, but that’s very much missing the point!).
This is why you see lots of people building on top of OSGi, but very few cases of passing OSGi benefits on into the application programming model (Eclipse RCP is a rare exception). When you build on top of OSGi, but don’t necessarily expose that model for end user application development, you can build to the OSGi model and make things work. When you need to provide a platform on which large numbers of existing enterprise libraries can be used it’s a different ball game. If we could just throw all that away and start again with libraries written explicitly for OSGi we’d be fine. We’ve made sure for example that the Spring Framework is fully able to run inside an OSGi Service Platform. But that’s not a realistic proposition. Alternatively we could wait for the developers of existing libraries to convert them all to run under OSGi out of the box (as we have done with Spring). But what’s the motivation for them to do that unless everyone else does it too? So we seem to be stuck in a chicken-and-egg situation. It’s a problem that the OSGi Enterprise Expert Group has spent a lot of time discussing over the past year.
This is the problem that the SpringSource Application Platform solves :- it bootstraps enterprise application development into the world of OSGi by making standard OSGi bundles with standard OSGi semantics work with existing enterprise application libraries.
I’d also like to re-emphasize that the platform is not just about OSGi : the OSGi support is one of the features we’re most excited about, but the SpringSource Application Platform is also an excellent server platform for deploying standard war files. We’ll describe the benefits the platform offers in such scenarios in later postings.
Hopefully this post has helped to clear up some of the confusion surrounding exactly how the SpringSource Application Platform relates to OSGi. If you’ve been following along so far, you might have picked up on another lurking problem: it’s all well and good to make existing enterprise libraries work under OSGi, but don’t you need to turn all of their jar files into OSGi bundles in order to be able to deploy them? Yes you do. And it turns out that’s a lot of work if you want to correctly version all of the imports and exports and ensure that you have correct symbolic names etc… The good news is that for hundreds of commonly used enterprise applications libraries, we’ve done the hard work for you and made the OSGi-ready versions available in the SpringSource Enterprise Bundle Repository…
SpringSource Enterprise Bundle Repository
The SpringSource Enterprise Bundle Repository is both a repository that can be used from Ivy and Maven, and also an online searchable database of enterprise libraries. You’ll find it at www.springsource.com/repository. You can browse for bundles by name, or just type in a search term to find bundles with matching names, exported packages, classes, or resources. You can also see the minimal (satisfying only the required dependencies) and maximal (satisfying as many of the optional dependencies as possible) transitive dependencies of any bundle.
From the FAQ:
“The SpringSource Enterprise Bundle Repository is a collection of open source libraries commonly used for developing enterprise Java applications with the Spring Framework. The repository contains jar files (bundles) and library definition (”.libd“) files. A library defines a collection of bundles that are often used together for some purpose (e.g. the ”Spring Framework“ library). There are hundreds of bundles contained in the repository.”
The repository meets the following criteria:
Every jar file in the repository is a valid OSGi bundle. Any jar you download from the repository can be deployed as-is into an OSGi Service Platform and the SpringSource Application Platform. It can also be used as a regular jar file outside of OSGi.
Every bundle and library has full version information associated with it. The package export information for a bundle contains version information, and the package import information for a bundle contains full version range compatibility information.
The repository is transitively complete. The mandatory dependencies of any bundle are guaranteed to also be in the repository. Most of the optional dependencies of any bundle in the repository will also be present. The bundles listed in any library definition are guaranteed to be in the repository.
The repository is self-consistent. Before any artefact is uploaded to the repository, we verify that it can be installed, resolved, and started in an OSGi Service Platform (using the same profile as the SpringSource Application Platform) alongside all of the other bundles in the repository.
The repository can be used from Ivy and Maven based builds.
To maintain these guarantees we have put in place a governance model around the publishing of artefacts to the repository. There is a JIRA instance against which you can raise requests for additional libraries to be included and to report any problems (relating to OSGi manifests etc.) with existing published artefacts.
Application Development Tools:
So far we’ve discussed the Spring-based programming model for developing applications as OSGi bundles, the availability of enterprise libraries to deploy into an OSGi Service Platform, and a runtime (the SpringSource Application Platform) that enables these legacy libraries to work in an OSGi runtime. The missing piece of the puzzle is the developer tools that make the creation of OSGi-based applications easy.
Eclipse already has OSGi development tools built-in. Since every Eclipse plugin is also an OSGi bundle, the Eclipse PDE tools (Plugin Development Environment tools) can be used for OSGi application development. However, the fact that these tools were primarily designed for the development of Eclipse plugins shows through and there are a couple of common frustrations when using them for OSGi application development. One is that the META-INF/MANIFEST.MF file can only be placed at the root of the project - which doesn’t work well with build tools such as Ivy and Maven, and the other is that you are restricted to a single target platform (collection of bundles to develop against) for your whole workspace. What is great about the PDE tools, and which you really need, is that they build the compilation classpath for your project from the OSGi manifest - so that you don’t have differences in classpath and class visibility between compile, test, and runtimes.
Alongside the SpringSource Application Platform we’ve also released a set of Eclipse plugins (available from the SpringSource Application Platform download page) that makes the development of OSGi applications easier, especially applications targeted at the SpringSource Application Platform. Your META-INF/MANIFEST.MF file can be in any source directory, and the tools build the compilation classpath from the manifest entries. Instead of a single target platform though, you can associate your project with a SpringSource Application Platform server defined to Eclipse (using the WTP facilities). The classpath for your project is then derived from the import statements in your manifest, resolved against other bundle projects in your workspace and the bundles installed in the associated server. You get the exact same interpretation of your classpath and dependencies at compile time as you do at runtime. And of course, the normal “deploy to server” options work too.
Here’s how the server looks when it’s running inside Eclipse:
And this screenshot shows how the classpath is managed with a “Bundle Dependencies” classpath container. Notice how packages that you have not imported in your manifest file are greyed out to indicate that you can’t currently access them.
Even better is how we’re able to take advantage of OSGi’s modularity. A set of projects (one per bundle) make up your application. When you change anything in the project, an additional incremental builder analyses the resources deltas and does a live update of the running bundle in the SpringSource Application Platform - so you’re continually running with the latest code : every time, all the time. That’s a great productivity boost and a great development experience.
Case Study
Matt Raible posted a blog entry about his adventures trying to get a Spring web application working under OSGi using Freemarker - without using the SpringSource Application Platform. This seemed like a good challenge application to test out what I said above about making existing enterprise libraries work. The good news is, this application runs very happily on the SpringSource Application Platform. Here are the steps I followed to make it work (total time, about 10 minutes):
Download the zip file from Matt’s blog
Run ‘mvn’
cp target/mpapp.war to the pickup directory of the Platform
Startup the platform: bin/startup.sh.
I got the following output to the console:
com.springsource.platform.deployer.core.DeploymentException: Unable to satisfy constraints of ‘myapp’ version ‘0.0.0’:
Cannot resolve: myapp Unsatisfied leaf constraints:
Bundle: myapp_0.0.0 - Import-Package: org.springframework.osgi.web.context.support; version=“0.0.0”
Did you mean: ‘org.springframework.osgi.context.support’?
Bundle: myapp_0.0.0 - Import-Package: freemarker.ext.servlet; version=“0.0.0”
Did you mean: ‘javax.servlet’?
Bundle: myapp_0.0.0 - Import-Package: freemarker.core; version=“0.0.0”
Did you mean: ‘org.hamcrest.core’?
Bundle: myapp_0.0.0 - Import-Package: freemarker.template; version=“0.0.0”
Did you mean: ‘org.antlr.tool’?
Bundle: myapp_0.0.0 - Import-Package: freemarker.cache; version=“0.0.0”
Did you mean: ‘org.apache’?
These are expected messages since I don’t have freemarker or the osgi.web.context support bundles installed in the platform.
Go to http://www.springsource.com/repository. Type “freemarker” into the search box, find the one matching entry and click on the link to download it. Copy the downloaded bundle in repository/bundles/usr
Simplify the manifest to point to the new bundles and libraries on the platform. The original manifest looked like this:
Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
org.springframework.osgi.web.context.support, org.springframework.context.support,
org.springframework.web.context, org.springframework.web.context.support,
org.springframework.web.servlet, org.springframework.web.servlet.mvc,
org.springframework.web.servlet.mvc.support, org.springframework.web.servlet.view,
org.springframework.ui, org.springframework.web.servlet.view.
freemarker, freemarker.cache,freemarker.core,freemarker.template,freemarker.ext.servlet
and I took it down to:
Import-Package: org.apache.commons.logging
Import-Library: org.springframework.spring;version=“[2.5.4,3.0.0)”
Import-Bundle: com.springsource.freemarker;version=“2.3.12”
When we know you are deploying a web application, the commonly required imports are automatically added at deployment time. Import-Library and Import-Bundle allow you to conveniently refer to libraries and bundles in a single statement. I also deleted the “Bundle-Classpath” entry as the application platform will automatically detect libraries in WEB-INF/lib and add them to the bundle classpath.
I edited web.xml and commented out the context-param declaration since there is no need to use a custom application context type here
Run ‘mvn’ again, and copy the myapp.war into the pickup directory.
The Application Platform automatically redeployed the application
Point a browser at http://localhost:8080/myapp/ …. SUCCESS!
I think this is a nice demonstration of the value proposition of the platform in smoothing the path of making enterprise libraries work under OSGi.
comments powered by Disqus
我敢肯定,大部分阅读此博客的人都会在昨天看到SpringSource Application Platform的发布。SpringSource Application Platform是一个由SpringSource公司开发的开源应用平台,它为开发者提供了一套完整的解决方案,用于构建、部署和管理企业级应用程序。
该平台的核心组件包括:
- Spring Framework:一个轻量级的Java开发框架,提供了控制反转(IoC)和面向切面编程(AOP)等功能,帮助开发者更高效地开发企业级应用。
- Tomcat:一个开源的Java Servlet容器,用于运行Java Web应用程序。
- Hyperic HQ:一个用于监控和管理服务器资源的管理工具,支持多种操作系统和虚拟化技术。
- Spring Roo:一个基于Spring Framework的快速开发工具,可以帮助开发者快速生成代码和配置。
- GWT Designer:一个用于开发Google Web Toolkit(GWT)应用程序的集成开发环境(IDE)。
SpringSource Application Platform旨在简化企业级应用的开发、部署和管理过程,提高开发效率和质量。通过使用这个平台,开发者可以专注于业务逻辑的实现,而不必花费大量时间处理底层的技术细节。
SpringSource Application Platform(简称SAPP)是一个基于Spring框架的应用开发平台,它为开发者提供了一整套工具和功能来简化企业级应用的开发、部署和管理。其主要功能包括:
-
集成开发环境(IDE):
- 提供代码编辑、调试和测试功能,支持多种编程语言和框架。
- 内置的Spring工具套件(STS),专为Spring应用程序开发而设计。
-
运行时管理:
- 提供Tomcat作为默认的Web服务器,支持其他Java EE兼容的服务器。
- 支持热部署,允许在不重启服务器的情况下更新应用程序。
-
数据管理和持久化:
- 集成了数据库访问层,支持JDBC、Hibernate等ORM框架。
- 提供数据源配置和管理功能,简化数据库连接和操作。
-
消息传递和集成:
- 集成了消息中间件(如ActiveMQ),支持异步通信和系统集成。
- 提供对RESTful服务的支持,方便构建微服务架构。
-
安全框架:
- 提供身份验证和授权机制,支持多种安全标准和协议。
- 集成Spring Security,提供细粒度的安全控制。
-
监控和管理:
- 提供应用程序的运行时监控和日志管理功能。
- 支持远程管理和控制,通过管理控制台进行操作。
-
云原生支持:
- 支持在云环境中部署和管理应用程序,提供与Kubernetes等容器编排工具的集成。
- 提供自动化部署和持续集成/持续交付(CI/CD)功能。
-
社区和生态系统:
- 拥有活跃的开发者社区,提供丰富的插件和扩展。
- 与Spring生态系统中的其他项目(如Spring Boot、Spring Cloud)紧密集成。
我敢肯定,大部分阅读此博客的人都会在昨天看到SpringSource Application Platform的发布。如果没有,请务必查看Rob的博客文章,其中描述了一些动机,编程模型和路线图。
我想在本文中直接回答几个常见问题。之后,我将描述另外两个激动人心的公告,它们补充了SpringSource Application Platform本身,但昨天却没有引起关注:SpringSource Enterprise Bundle存储库和Eclipse的Application Platform工具。这些共同完成了有关使用Spring基于OSGi的企业应用程序开发的故事。
我在过去24小时内多次听到的问题是:OSGi有什么问题-为什么我们不能只使用香草OSGi服务平台(例如Equinox,Felix或Knopflerfish)而不是SpringSource应用程序平台?
OSGi绝对没有错。
OSGi是一个很好的基础和服务平台-这就是我们和许多其他人选择在其基础上进行构建的原因。它在广泛的行业和应用程序中得到了证明,并为诸如Eclipse和IBM的WebSphere等应用程序以及其他多家供应商的中间件堆栈提供了基础。
直接按照OSGi规范API进行编程缺乏我们对企业应用程序所期望的某些素质-例如使用依赖项注入和创建易于在容器外部进行单元和集成测试的应用程序的能力。直接按照OSGi规范进行编程的API也会迫使您以相对较低的水平来处理OSGi平台的动态性-在运行时停止,启动,安装和更新所依赖的模块和服务时该怎么办?但是在这里,我们并没有克服Spring Dynamic Modules项目无法克服的根本障碍。使用Spring动态模块构建的应用程序可以在任何标准OSGi服务平台上运行,并且我们针对Equinox,Felix和Knopflerfish测试了所有构建版本。我们致力于确保Spring动态模块和基于Spring的编程模型保持运行时中立。随着SpringSource应用程序平台的引入,这一立场不会改变。