【问题标题】:GlassFish - How to get datasource from OSGI bundleGlassFish - 如何从 OSGI 包中获取数据源
【发布时间】:2012-04-03 00:53:33
【问题描述】:

我有这个获取数据源服务的 Apache Felix 激活器:

import javax.sql.DataSource;
import java.sql.SQLException;

import java.util.Properties;
import org.DX_57.osgi.SH_27.api.SessionHandle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;


public class SessionHandleApp implements BundleActivator {

    public static final String DSNAME = "jdbc/Oracle";
    public ServiceTracker st;

    @Override
    public void start(final BundleContext bc) throws Exception {
        debug("Activator started");


        Filter filter = bc.createFilter("(&" + "(" + Constants.OBJECTCLASS
                + "=" + DataSource.class.getName() + ")" + "(jndi-name="
                + DSNAME + ")" + ")");
        st = new ServiceTracker(bc, filter, null) {

            @Override
            public Object addingService(ServiceReference reference) {
                DataSource ds = (DataSource) bc.getService(reference);
                try {
                    debug(ds.getConnection().toString());

                SessionHandle sh = new SessionHandleImpl();
                                sh.setDataSource(ds);
                    ServiceRegistration registerService = bc.registerService(SessionHandle.class.getName(), sh, new Properties());

                } catch (SQLException e) {
                }

                return super.addingService(reference);
            }

            @Override
            public void removedService(ServiceReference reference,
                    Object service) {
                super.removedService(reference, service);
            }

        };
        st.open();                
    }

    public void stop(BundleContext bc) throws Exception {
        boolean ungetService = bc.ungetService(bc.getServiceReference(SessionHandle.class.getName()));
        st.close();
    }

    private void debug(String msg) {
        System.out.println("JDBCBundleActivator: " + msg);
    }

}

此解决方案有效,但使用数据库驱动程序类名配置 JDBC 的传统方法在 OSGi 中效果不佳。

我必须如何编写一个包含初始化数据源并将其作为服务提供的激活器的包?

【问题讨论】:

    标签: java glassfish osgi apache-felix


    【解决方案1】:

    我认为你很困惑。上面的代码没有使用 JDBC 驱动。它使用 JDBC 数据源作为服务。在 GlassFish 中,创建 DataSource 服务的最简单方法是使用 GlassFish 管理操作,例如“asadmin create-jdbc-resource with a JNDI name”。然后 GlassFish 自动将其注册为具有注册属性 jndi-name=YourSuppliedJndiName 的 DataSource OSGi 服务。

    【讨论】:

    • 是的,上面的代码没有直接使用 JDBC 驱动程序,这是您最关心的问题,所以在这方面是正确的。另一个问题是代码的某些部分看起来很可疑。例如,当所需的 DataSource 服务可用时,您正在注册一个新的 SessionHandle 服务,但是当所述服务消失时,您并没有取消注册它。理想情况下,您应该将 registerService 作为服务跟踪器的一个字段,以便您可以在服务跟踪器的 removedService() 方法中取消注册。
    • 您会更正代码吗?上传到 www.pastebin.com 我可以创建一个简单的激活器,但是我没有足够的知识来使它正确。
    【解决方案2】:

    您可以检查Gemini DBAccess project,它将DataSourceFactory 导出为OSGi 服务,因此您可以直接使用它。

    【讨论】:

    • 我从 Gemini DBAccess 中找到了这个示例:pastebin.com/S8rvbNhZ 我发现很难用 Apache Felix 实现它。我没有足够的 OSGI 练习。
    猜你喜欢
    • 2012-07-30
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2011-11-25
    • 2014-09-09
    • 2015-07-18
    • 2015-01-14
    相关资源
    最近更新 更多