0

我想在本地Glassfish服務器上使用聲明式服務來做一個簡單的OSGi服務。提供的插件始終處於活動狀態。OSGi聲明式服務注入

我與注入我的servlet消耗我的服務的麻煩,當servlet被調用,因爲它不是該得到一個與服務引用注入同一對象的引用爲空。

我通過在我的引用setter中放置一個斷點來測試它,並且我看到我的服務被注入,但是當我點擊將我的servlet調用到我的應用程序中的按鈕時,服務引用爲空,因爲它不相同對象(即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> 

我的servlet是

@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> 

而且我試過,但沒有運氣,因爲我的servlet似乎並沒有找到(錯誤404 - 所請求的資源()不可用。),來做爲彼得柯瑞恩斯寫有:How to consume OSGi service from OSGi HTTP Service

所以我修改我的servlet像這樣:

@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> 

訪問servlet爲了測試上面我在我的部署捆綁org.apache.felix.http.api-2.2.1,org.apache.felix.http。白板-2.2.1就像在帖子中一樣。沒有找到是否有轉換。

另外我用org.apache.felix.webconsole-4.2.0檢查了所有的軟件包,並且服務在那裏運行,它說我的使用者軟件包正在使用它。

+0

Wakarimasen deshita ... –

回答

0

您有兩方創建您的servlet的實例。 DS和另一個是Web容器。你不能有2個主人。 Web容器基本上必須負責,因爲它只會將請求發送到它創建的servlet實例。

如果有一個支持Web容器和DS的實現,那麼您將被設置。但我從來沒有聽說過這樣的事情。

我不知道Glassfish是否支持OSGi Web Application Specification(Ch 128)。如果是這樣,那麼可以按照128.6中的描述與OSGi服務層進行交互。

+0

你好,我發現我面臨2個容器管理我的代碼。由於看起來我使用Glassfish OSGi Web Container,因此我可以通過getServletContext()。getAttributes(「osgi-bundle」)來訪問我的bundle上下文,就像在spec中一樣,並從那裏獲取我的服務,想知道是否有某個配置在GlassFish或插件/工具或任何其他方式來創建我的servlet,讓我使用注入 – HellDevils

+0

不,它是/或。 –

+0

好了,我將按照規範訪問服務,所以從servlet上下文中使用getServletContext()。getAttributes(「osgi-bundle」)來獲取我的服務和服務參考 – HellDevils

相關問題