Eclipse Problem Figured Out

July 23, 2008 by alexaggregate

I’ve been able to find why Eclipse doesn’t update the classes for OSGi in some cases. To find when is starts going wrong. I got the hint here at Apache Felix FAQ.

I was using cross-references. My bundles:

DAOLayer was using com.ak.domain.WebSite and exporting com.ak.dao.WebSiteDAO

MainLayer was using com.ak.dao.WebSiteDAO and exporting com.ak.domain.WebSite

So when I remove this cross-reference, it starts updating classes. This, however, doesn’t happen in all cases. Seems like it stops working only when the classes in cross-referenced packages also reference each other.

Over all, here are the conclusions:

1. Don’t cross-reference packages that rely on each other. Maybe it’s OSGi problem.

2. If bundle A has package package1 and bundle B has package with the same name (package1), then bundle B can not export this package for bundle A to use.

3. !!IMPORTANT!! Let’s say we’ve got BundleA and BundleB. If BundleB uses SomeClass in a method that is called by BundleA (even if BundleA has no idea of SomeClass), you need to explicitly export package of SomeClass in BundleB.

Again,

IF (

BundleB / package com.Big / BigClass has method:

public void printSmth () { new com.small.SomeClass(); }

AND BundleA imports com.Big in order to call com.Big.BigClass.printSmth(),

) THEN {

BundleB has to export com.small package

}

— doesn’t make too much sense, but this is how it works for me.

To fix all the problems, I moved Website class to DAOLayer. I know its better place is in MainLayer, but it won’t work this way. They (WebSite and WebSiteDAO) are too tightly coupled and therefore don’t work if they’re in different bundles.

Current Problems

July 22, 2008 by alexaggregate

First off, I’m getting ‘com.ibatis.sqlmap.client.SqlMapException: There is no statement named getWebsite in this SqlMap.’ – even though there is one. Even if I try to call it with namespace, like WebSite.getWebSite. I also tried ‘allWebsites’ to get a java.util.List.

Second thing, somehow I can’t update the files in Eclipse. When I change my WebSiteDAOImpl with iBatis connection, and Run the project, I keep hearing same old ‘com.ibatis.sqlmap.client.SqlMapException: There is no statement named getWebsite in this SqlMap.’ Even when I comment all of the lines. So it’s obvious that the class just doesn’t get reloaded (I tried OSGi command ’shutdown’, stopping the execution, reopening Eclipse, restarting Linux).

Then I tried deleting ‘bin’ folder, so that it sees I don’t have classes and just remakes them. What it says is ‘i don’t see your classes’.

________________________________________________________

Short note about Eclipse.

1. Sometimes it just ‘loses’ your classes and says it doesn’t see them, when in reality they’re in place.

2. Sometimes its MANIFEST editor won’t save any changes. What helps is reopening Eclipse

Adding iBatis to OSGi application

July 22, 2008 by alexaggregate

Last blog post leaves us with working JDBC/Spring/OSGi. Now we want to sweet it with iBatis.

1. I used the same way as with ‘mysql-connector’ to add iBatis library jar (it’s the only one we need). So, again, I added it to JARs folder, then to bundle’s classpath and exported add com.ibatis packages.

2. Then what goes inside of iBatis folder:

File 1. Configuration file: ibatisconfig.xml:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE sqlMapConfig
PUBLIC “-//ibatis.apache.org//DTD SQL Map Config 2.0//EN”
“http://ibatis.apache.org/dtd/sql-map-config-2.dtd”>

<sqlMapConfig>

<settings useStatementNamespaces=”true”/>

<transactionManager type=”JDBC”>
<dataSource type=”SIMPLE”>
<property name=”JDBC.Driver” value=”com.mysql.jdbc.Driver”/>
<property name=”JDBC.ConnectionURL”
value=”jdbc:mysql://localhost/RELATE”/>
<property name=”JDBC.Username” value=”root”/>
<property name=”JDBC.Password” value=”123″/>
</dataSource>
</transactionManager>

<sqlMap url=”file:///home/ayarmula/projects/osgi/DAOLayer/ibatis/mapping/WebSite.xml”/>

</sqlMapConfig>

File 2. Mapping: WebSite.xml

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!DOCTYPE sqlMap
PUBLIC “-//ibatis.apache.org//DTD SQL Map 2.0//EN”
“http://ibatis.apache.org/dtd/sql-map-2.dtd”>
<sqlMap namespace=”WebSite”>

<resultMap class=”com.ak.domain.WebSite” id=”webSiteResultMap”>
<result property=”id” column=”ID”
javaType=”java.lang.Long” />
<result property=”displayName” column=”DISPLAY_NAME”
javaType=”java.lang.String” />

</resultMap>

<select id=”getWebsite” resultClass=”com.ak.domain.WebSite” resultMap=”webSiteResultMap”>
select ID as ID,
DISPLAY_NAME as displayName
from WEBSITE
where ID = #value#
</select>
</sqlMap>

3. So having this set there’s one thing left, use it from the application.

First of all, for Eclipse under Linux, resource ‘.’ folder is home/user. So include that in paths.

In SomeDAOImpl I tried using

Reader reader = Resources.getResourceAsReader(“projects/osgi/DAOLayer/ibatis/ibatisconfig.xml”);
SqlMapClient sqlMapper =
SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
Object ws =
sqlMapper.queryForObject(“WebSite.getWebsite”, new Integer(108));

but it kept telling that the resource was incorrect. I could get it working by:

Reader reader = new BufferedReader(new FileReader(new File(“projects/osgi/DAOLayer/ibatis/ibatisconfig.xml”)));

Also, there’s a trick in path to mapping file. As you can see about in ibatisconfig.xml, it only worked for me as <sqlMap url=”file:///home/ayarmula/projects/osgi/DAOLayer/ibatis/mapping/WebSite.xml”/>.

Quick Start OSGi/Spring/JDBC

July 22, 2008 by alexaggregate

Ok, so here’s what we basically do to start OSGi/Spring/JDBC:

1. Create 2 OSGi bundles, Main and DAO.

2. In DAO, create com.you.dao.SomeDAO interface and com.you.dao.impl.SomeDAOImpl. DAO will have DataSource param and some JDBC stuff that it does.

3. In META-INF/MANIFEST.mf add com.you.dao to export packages.

4. In META-INF/spring (create it) create 2 xml files, one will create SomeDAOImpl (named ’someDAO’) and map DataSource to it (it includes DataSource bean definition as well, to be quick), second one will expose SomeDAOImpl under its interface SomeDAO to OSGi. Like:

<osgi:service id=”someDAOOSGiService” ref=”someDAO”
interface=”com.you.dao.SomeDAO”>
</osgi:service>

5. In Main, create some class (MainClass) and a parameter for SomeDAO. We’ll use it later

6. In Main, make sure META-INF/MANIFEST.mf imports com.you.dao package. Also, META-INF/spring of this bundle needs to ‘catch’ SomeDAO:

<osgi:reference id=”someDAOService” interface=”com.you.dao.SomeDAO”/>

Also, we need to link this bean to HelloClass like this:

<bean name=”helloClass” class=”…HelloClass” init-method=”start”>

<property name=”webSiteDAO” ref=”webSiteDAOService”/>

</bean>

7. Now in helloClass we can create “public void start()” method and use SomeDAO.

8. Dependencies. Just like it’s written here, but including my comment in previous post. Don’t forget to create New Project – Plug-in Development – Plug-in From existing JAR archive and include commons-logging.jar there.

Eclipse configuration for JDBC/Spring

July 22, 2008 by alexaggregate

The article from JavaWorld woulda been just fine, if it hadn’t left out some details:

1. Spring DM (neither 1.0.2 nor the latest 1.1.0) doesn’t have spring-jdbc, spring-tx packages in it. They’re available at Spring website and then you can import them just like every other package (Import – Plug-in Development – Plug-ins and Fragments). (page 2)

2. You can use log4j from Spring DM, works for me (page 2).

3. The last page tells us to put “mysql connector” to a ‘JARs folder’ folder, and then add it to classpath in MANIFEST – Runtime. What it doesn’t tell is that you also need to go to MANIFEST – Exported Packages – Add and add com.mysql.jdbc (as well as other packages available) (page 7).