0

ローカルの Glassfish サーバーで Declarative Services を使用して単純な OSGi サービスを実行しようとしています。提供するプラグインは常にアクティブです。

サービスを消費するサーブレットへの注入で問題が発生しました。サービス参照が注入されたオブジェクトと同じオブジェクトではないため、サーブレットが呼び出されると参照が null になります。

参照セッターにブレークポイントを設定してテストしたところ、サービスが注入されていることがわかりましたが、サーブレットをアプリケーションに呼び出すボタンをクリックすると、サービス参照は同じオブジェクトではないため null になります (つまり、取得します)。 servlet_Instance #1 に注入されますが、servlet_Instance #2 でメソッドを呼び出します.実行時にサービスを見つけて使用できるため、少し詳細が欠けているに違いありません

final BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
     loggingTestServiceInterface = (LoggingTestServiceInterface) bundleContext.getService(bundleContext
     .getServiceReference(LoggingTestServiceInterface.class.getName()));

XML ファイルの生成に使用するプラグイン: maven-scr-plugin

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.14.0</version>
<executions>
    <execution>
        <id>generate-scr-scrdescriptor</id>
        <goals>
            <goal>scr</goal>
        </goals>
    </execution>
</executions>
<configuration>
    <supportedProjectTypes>
        <supportedProjectType>war</supportedProjectType>
        <supportedProjectType>jar</supportedProjectType>
        <supportedProjectType>bundle</supportedProjectType>
    </supportedProjectTypes>
</configuration>
</plugin>

これは私のサービスクラスです

@Component(immediate = false, name = "Shikashi", service = {LoggingTestServiceInterface.class}, enabled = true)
public class LoggingTestService implements LoggingTestServiceInterface
{
private final LoggerUtils loggerUtils = new LoggerUtils();

public LoggingTestService()
{
}

@Activate
public void start(final BundleContext bundleContext)
{
    System.out.println("StartTest Service Fune");
}

@Deactivate
public void stop()
{
    System.out.println("Stop Test Service Jitensha");
}

@Modified
public void modify()
{
    System.out.println("Stop Test Service onnanogo");
}

private Logger createLogger(final Class<?> clazz)
{
    return Logger.getLogger(clazz);
}

@Override
public void logDebug(final Class<?> clazz, final String message)
{
    logDebug(clazz, message, null);
}
    @Override
public void logDebug(final Class<?> clazz, final String message, final Throwable throwable)
{
    final Logger logger = createLogger(clazz);
    logger.debug(message, throwable);
}

}

生成された XML は

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<scr:component enabled="true" immediate="false" name="Shikashi" activate="start" deactivate="stop" modified="modify">
    <implementation class="com.sti.logging.service.LoggingTestService"/>
    <service servicefactory="false">
        <provide interface="com.sti.loggingservices.serviceinterface.LoggingTestServiceInterface"/>
    </service>
</scr:component>

私のサーブレットは

@WebServlet(name = "Wakarimashita", urlPatterns = { "/Wakarimashita"})
@Component
public class Wakarimashita extends HttpServlet
{
private LoggingTestServiceInterface loggingTestServiceInterface;

@Override
protected void doGet(final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse) throws ServletException, IOException
{
    // Method just to setup the Servlet to understand how it works

    final String language = "language";
    final String path = "/sigbud/language/";

    if (httpServletRequest.getParameter(language) != null)
    {
        if (httpServletRequest.getParameter(language).equalsIgnoreCase("Nihongo"))
        {
            httpServletResponse.sendRedirect(path + "nihongo.jsp");
        }
        else if (httpServletRequest.getParameter(language).equalsIgnoreCase("Eigo"))
        {
            httpServletResponse.sendRedirect(path + "eigo.jsp");
        }
        else if (httpServletRequest.getParameter(language).equalsIgnoreCase("Funansugo"))
        {
            httpServletResponse.sendRedirect(path + "funansugo.jsp");
        }
        else
        {
            httpServletResponse.sendRedirect(path + "unknown.jsp");
        }
    }
    else
    {
        super.doGet(httpServletRequest, httpServletResponse);
    }

    loggingTestServiceInterface.logError(getClass(), "Wakarimasen");
}
    @Reference(service = LoggingTestServiceInterface.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC)
public void bindLoggingTestServiceInterface(final LoggingTestServiceInterface loggingTestServiceInterface)
{
    this.loggingTestServiceInterface = loggingTestServiceInterface;
}

public void unbindLoggingTestServiceInterface(final LoggingTestServiceInterface loggingTestServiceInterface)
{
    if (this.loggingTestServiceInterface.equals(loggingTestServiceInterface))
    {
        this.loggingTestServiceInterface = null;
    }
}
@Activate
public void start(final BundleContext bundleContext)
{
    System.out.println("StartTest Service Taisho");
}

@Deactivate
public void stop()
{
    System.out.println("Stop Test Service Fukutaisho");
}

@Modified
public void modify()
{
    System.out.println("Stop Test Service san jyû kyû");
}
}

生成された XML

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<scr:component name="com.sti.sigbud.servlet.Wakarimashita" activate="start" deactivate="stop" modified="modify">
    <implementation class="com.sti.sigbud.servlet.Wakarimashita"/>
    <reference name="LoggingTestServiceInterface" interface="com.sti.loggingservices.serviceinterface.LoggingTestServiceInterface" cardinality="1..1" policy="dynamic" bind="bindLoggingTestServiceInterface" unbind="unbindLoggingTestServiceInterface"/>
</scr:component>

また、Peter Kriens がそこに書いたように、サーブレットが見つからないように見えるため (エラー 404 - 要求されたリソース () は利用できません)、運がありませんでした: OSGi HTTP サービスから OSGi サービスを消費する方法

そこで、サーブレットを次のように変更しました。

@Component(service = Servlet.class, property = {"alias=/Wakarimashita"})
public class Wakarimashita extends HttpServlet

生成された XML は

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<scr:component name="com.sti.sigbud.servlet.Wakarimashita" activate="start" deactivate="stop" modified="modify">
    <implementation class="com.sti.sigbud.servlet.Wakarimashita"/>
    <service servicefactory="false">
        <provide interface="javax.servlet.Servlet"/>
    </service>
    <property name="alias" value="/Wakarimashita"/>
    <reference name="LoggingTestServiceInterface" interface="com.sti.loggingservices.serviceinterface.LoggingTestServiceInterface" cardinality="1..1" policy="dynamic" bind="bindLoggingTestServiceInterface" unbind="unbindLoggingTestServiceInterface"/>
</scr:component>

JSP からサーブレットにアクセスします

<form action="Wakarimashita" method="GET">
        <input type="text" name="language" size="50"/>
    <input type="submit" value="Submit" />
</form>

上記をテストするために、投稿と同じように、デプロイされたバンドル org.apache.felix.http.api-2.2.1、org.apache.felix.http.whiteboard-2.2.1 に含まれています。装着するスイッチがあるかどうかはわかりませんでした。

また、org.apache.felix.webconsole-4.2.0-all バンドルを確認したところ、サービスが稼働中であり、コンシューマー バンドルがそれを使用していると表示されます。

4

1 に答える 1

1

サーブレットのインスタンスを作成する 2 つの当事者がいます。1 つは DS で、もう 1 つは Web コンテナーです。2 つのマスターを持つことはできません。Web コンテナーは、作成したサーブレットのインスタンスにのみ要求を送信するため、基本的に担当する必要があります。

Web コンテナーと DS の両方をサポートする実装があれば、問題はありません。しかし、私はそのようなことを聞​​いたことがありません。

Glassfish が OSGi Web アプリケーション仕様 (Ch 128) をサポートしているかどうかはわかりません。そうであれば、128.6 で説明されているように、OSGi サービス層と対話できます。

于 2013-10-02T20:14:52.557 に答える