本来觉得在已经集成好sping osgi的基础上,再加上spring数据层比较简单, 但是遇到一些问题竟然阻塞好几天。
------------------------------------------------------------------------------------------------------------------------------------------------------
一 列一下大概有这几个问题:
1、equinox启动时,从configuration文件夹貌似读取了很多文件缓存,导致我更新进去的包,没能按预期运行,好长时间摸不着头脑。
于是增加了一点EclipseStarter启动前的准备工作——将configuration文件夹全部删掉。
2、包兼容性问题。因为调试时,有上面一个因素干扰,我也不确定是不是有包兼容性的问题,但是还是从spring.framework网站重新下了一套版本一致的jar包下来。
所有spring.framework的jar包可以从这里下:http://ebr.springsource.com/repository/app/
我用的大概如下,其中osgi.core 、 osgi.io 、 osgi.extender三个包支持osgi下spring配置,jdbc、transaction、mysql.djbc支持我做spring持久层调试,其他都是spring依赖~~
以前用了http://s3.amazonaws.com/dist.springframework.org/milestone/OSGI/spring-osgi-2.0.0.M1-with-dependencies.zip 这里面的包,包不怎么全,导致了想新加一些包时,频频遇到兼容性问题。后来找到了官方网站,终于解脱了。
3、因为springDM已经被交给Eclipse了,改名gemini.blueprint,所以maven中央仓库关于spring.framework的包是不全的,目前我只找到上面说的那个网站可以下全。这就造成,编译我自己的jar包的时候,如果依赖很多jar包,有些可以用maven去依赖,有些要配置buildPath,这个看Eclipse怎么报错了,要是它说buildPath里面的哪个类找不到,那就用maven依赖。我碰到的就是org.eclipse.osgi这个包,需要用maven依赖,不然编不过。
4、为了实验简便,我没有用连接池,datasource配置直接用的com.mysql.jdbc.Driver去驱动,根据我最后的实验结果,需要在我的调用者jar包中,配置Import-Package: com.mysql.jdbc ,并且还需要在 org.springframework.jdbc的MENIFEST.MF中,做同样配置。否则一个报错找不到驱动类(大概是can't load driverclassname之类的提示),一个报错找不到合适驱动(can not find a suitable driver for jdbc:mysql://localhost:3306/web)。
在自己jar包中,加驱动依赖也就算了,还要在第三方jar包中修改MENIFEST.MF文件......我也觉得十分不优雅,但是这个org.springframework.jdbc获取连接时,用的是自己的类加载器加载驱动,我能怎么样呢。。
除了修改org.springframework.jdbc的MENIFEST.MF,应该还有至少两个方法:把驱动放到jre/lib/ext下面去,或者用osgi中bundle的父加载器,也就是公共加载器去加载驱动。这样做的话,就完全不需要在Import-Package里面配置导入驱动包了。但是时间有限暂时就不搞那个了。
------------------------------------------------------------------------------------------------------------------------------------------------------
二 看下实验结果吧。。
step 1
http://ebr.springsource.com/repository/app/ 里面下载上图中所有jar包,放入spring-ogsi-min/plugins文件夹。
下载org.eclipse.osgi-3.7.1.jar,放到spring-osgi-min文件夹。
step 2
按照我上一遍文章从外部启动equinox,得到一个start.jar包,放到spring-osgi-min文件夹。
java -jar start.jar 测试一下是不是能启动的都启动了。
step 3
新建一个maven工程,其中pom文件大概如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test.springdb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>springdb</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
<version>3.7.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>springdb</Bundle-SymbolicName>
<Export-Package></Export-Package>
<Import-Package>*,com.mysql.jdbc</Import-Package>
<!-- <Require-Bundle>com.springsource.com.mysql.jdbc</Require-Bundle> -->
<Bundle-Vendor>haha</Bundle-Vendor>
<Include-Resource>/META-INF = /META-INF</Include-Resource>
<Bundle-Activator>test.springdb.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
新建META-INF/spring/jdbc.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url" value="jdbc:mysql://localhost:3306/web"></property>
<property name="username" value="web"></property>
<property name="password" value="web"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="serviceCenter" class="test.springdb.ServiceCenter"
factory-method="getInstance">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
</beans>
ServiceCenter类:
package test.springdb;
import org.springframework.jdbc.core.JdbcTemplate;
public class ServiceCenter {
private static ServiceCenter INSTANCE = new ServiceCenter();
private JdbcTemplate jdbcTemplate;
private ServiceCenter() {
}
public static ServiceCenter getInstance() {
return INSTANCE;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
Activator类:
package test.springdb;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class Activator implements BundleActivator {
// private static Logger logger = LoggerFactory.getLogger(Activator.class);
public void start(BundleContext arg0) throws Exception {
new Thread(new Runnable(){
public void run() {
while (ServiceCenter.getInstance().getJdbcTemplate() == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
JdbcTemplate jt = ServiceCenter.getInstance().getJdbcTemplate();
jt.execute("insert into user values('lzl', 1000);");
System.out.println("insert one row into user!");
}
}).start();
}
public void stop(BundleContext arg0) throws Exception {
// TODO Auto-generated method stub
}
}
这个编译出来的test.springdb-0.0.1-SNAPSHOT.jar包,放到 spring-osgi-min/plugins里面去。
step 4
修改org.springframework.jdbc的MENIFEST.MF文件
在Import-Package的最后,添加上:
,com.mysql.jdbc;version="0";resolution:="optional"
当然,加了以后,要按MENIFEST.MF文件的格式整理好。
step 5
mysql数据库的准备,就是下个最新版本的mysql。
新建一个数据库名字也是web,新增一个表user,列名分别是 name age,类型分别是字符串和整型。
添加一个 web用户,密码也是web,具备web数据库的所有权限。
然后 java -jar start.jar, 如果输出了
insert one row into user!
那么大功告成。