Karaf 4.0.1中使用声明服务的null服务问题

时间:2015-09-23 19:13:17

标签: nullpointerexception repository osgi apache-karaf declarative-services

我正在尝试创建一个可部署在karaf上的服务,该服务将文件导入存储库。我的项目设置方式是我有一个命令行类来处理在karaf中创建命令(通过使用org.apache.felix.gogo.commands注释以及blueprint.xml文件)和调用服务,以及处理服务实施的单独项目。

该命令在karaf中创建没有问题,我可以使用相应的参数调用它,但由于导入服务为null,我在运行它时总是会得到一个空指针异常。运行scr:导入服务和存储库的详细信息返回此信息:

**karaf@root()> scr:details 

com.inovexcorp.myproject.service.repository.memory 
Component Details
  Name                : com.inovexcorp.mmyproject.service.repository.memory
  State               : ACTIVE
  Properties          : 
    service.pid=com.inovexcorp.myproject.service.repository.memory.2d2dba73-30e2-4ce8-8dd0-2246bd5628b7
    repositorytype=memory
    service.factoryPid=com.inovexcorp.myproject.service.repository.memory
    component.name=com.inovexcorp.myproject.service.repository.memory
    felix.fileinstall.filename=file:/home/zachary/karaf/apache-karaf-4.0.1/etc/com.inovexcorp.myproject.service.repository.memory-cli-rdf-service.cfg
    component.id=1
    repositoryId=cli-rdf-service

References**

**karaf@root()> scr:details 
org.myproject.etl.rdf.importer.impl.RDFImportServiceImpl 

Component Details
  Name                : org.myproject.etl.rdf.importer.impl.RDFImportServiceImpl
  State               : ACTIVE
  Properties          : 
    repository.target=(repositorytype=memory)
    component.name=org.myproject.etl.rdf.importer.impl.RDFImportServiceImpl
    component.id=2

References
  Reference           : repository
    State             : satisfied
    Multiple          : single
    Optional          : mandatory
    Policy            : static
    Service Reference : Bound Service ID 175 (com.inovexcorp.myproject.service.repository.memory)**

以下是CLI和服务实现包的标题:

**karaf@root()> headers 294

importer (294)

Bnd-LastModified = 1443035070538

Build-Jdk = 1.7.0_85

Built-By = zachary

Created-By = Apache Maven Bundle Plugin

Manifest-Version = 1.0

Tool = Bnd-1.50.0

Bundle-ManifestVersion = 2

Bundle-Name = importer

Bundle-SymbolicName = importer

Bundle-Version = 0.0.1.SNAPSHOT

Import-Service = 
    org.myproject.etl.rdf.importer.api.RDFImportService;multiple:=false

Import-Package = 
    org.apache.felix.gogo.commands;version="[0.10,1)",
    org.apache.karaf.shell.console;version="[2.2,3)",
    org.myproject.etl.rdf.importer.api;version="[0.0,1)",
    org.openrdf.rio;version="[2.7,3)",
    org.osgi.service.blueprint;version="[1.0.0,2.0.0)"**


karaf@root()> headers 291

rdf.import (291)
----------------
Bnd-LastModified = 1442862863229
Build-Jdk = 1.7.0_85
Built-By = zachary
Created-By = Apache Maven Bundle Plugin
Manifest-Version = 1.0
Service-Component = OSGI-INF/org.myproject.etl.rdf.importer.impl.RDFImportServiceImpl.xml
Tool = Bnd-1.50.0

Bundle-ManifestVersion = 2
Bundle-Name = rdf.import
Bundle-SymbolicName = rdf.import
Bundle-Version = 0.0.1.SNAPSHOT

Import-Service = 
    org.openrdf.repository.Repository

Export-Package = 
    org.myproject.etl.rdf.importer.api;
        uses:=org.openrdf.rio;
        version=0.0.1.SNAPSHOT
Import-Package = 
    org.myproject.etl.rdf.importer.api,
    org.openrdf.model;version="[2.7,3)",
    org.openrdf.model.impl;version="[2.7,3)",
    org.openrdf.repository;version="[2.7,3)",
    org.openrdf.rio;version="[2.7,3)",
    org.osgi.service.component;version="[1.1,2)"

我已经陷入了这个问题一段时间了,如果有人有任何关于这个问题的信息,我会非常感激!

编辑:添加源代码以澄清

CLI类:

package org.myproject.cli.importer;

import java.io.File;

import org.apache.felix.gogo.commands.Argument;
import org.apache.felix.gogo.commands.Command;
import org.apache.karaf.shell.console.OsgiCommandSupport;
import org.openrdf.rio.RDFFormat;
import org.myproject.etl.rdf.importer.api.RDFImportService;



@Command(scope = "myproject", name = "import", description = "Imports objects to a repository")
public class CLIImporter extends OsgiCommandSupport{


    private RDFImportService importService;


    @Argument(index = 0, name = "repId", description = "The id of the repository the file will be imported to", required = true, multiValued = false)
    String repositoryId = null;

    @Argument(index = 1, name = "file", description = "The file to be imported into the repository", required = true, multiValued = false)
    String file = null;

    @Argument(index = 2, name = "continueOnError", description = "Optional: If true, continue parsing even if there is an error on a line.", required = true, multiValued = false)
    boolean continueOnError = false;

    @Argument(index = 3, name = "fileType", description = "Optional: Specify the file type if the one given is unsupported by Sesame.", required = false, multiValued = false)
    String fileType = null;

    @Argument(index = 4, name = "help", description = "Optional: If true, display a help menu.", required = false, multiValued = false)
    boolean help = false;



    public RDFImportService getImportService() {
        return importService;
    }


    public void setImportService(RDFImportService importService) {
        this.importService = importService;
    }

    @Override
    protected Object doExecute() throws Exception {

        File newFile = new File(file);

        System.out.println(repositoryId + " " + file + " " + continueOnError + " " + importService);

        if(fileType == null && help == false){
            importService.importFile(repositoryId, newFile, continueOnError);
        }
        else if(help == false){
            importService.importFile(repositoryId, newFile, continueOnError, RDFFormat.forMIMEType(fileType));
        }
        else if(fileType == null){
        //  impService.importFile(repositoryId, file, continueOnError, help);
        }
        else{
        //  impService.importFile(repositoryId, file, continueOnError, fileType, help);
        }

        return null;
    }
}

ImportServiceImpl类:

package org.myproject.etl.rdf.importer.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.myproject.etl.rdf.importer.api.RDFImportService;
import org.openrdf.model.Resource;
import org.openrdf.model.impl.BNodeImpl;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParseException;
import org.openrdf.rio.Rio;
import org.osgi.service.component.ComponentContext;

import aQute.bnd.annotation.component.Component;
import aQute.bnd.annotation.component.Reference;

@Component(provide = RDFImportService.class, immediate=true)
public class RDFImportServiceImpl implements RDFImportService{



    private Repository repository;

    private ComponentContext context;

    private RepositoryConnection repConnect;

    private Resource resource = new BNodeImpl("string");


    @Reference(target="(repositorytype=memory)")
    public void setRepository(Repository repository) {
        this.repository = repository;
    }




    public void importFile(String repositoryID,  File file, Boolean cont) {

        try {
            if (file == null) {
                throw new FileNotFoundException();
            }

            RDFFormat format = Rio.getParserFormatForFileName(file.getName());


            if (format == null) {
                throw new IOException();
            }

            System.out.println("Repository connecting...");
            repConnect = repository.getConnection();

            repConnect.add(file, null, format, resource);

            System.out.println("Repository set!");
            System.out.println(repConnect.isEmpty());

            System.out.println("Executing Import command");
            System.out.println("Arguments passed: " + repositoryID + " " + file);





        } catch (FileNotFoundException e) {
            System.out.println("FnF Exception!");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("IOException! File type not supported by Sesame.");
            e.printStackTrace();
        } catch (RepositoryException e) {
            System.out.println("Repository Exception!");
            e.printStackTrace();
        } catch (RDFParseException e) {
            System.out.println("RDFParseException! There was an error parsing the RDF file.");
            e.printStackTrace();
        }

    }


    public void importFile(String repositoryID,  File file, Boolean cont, RDFFormat format)  {

        try {
            if (file == null) {
                throw new FileNotFoundException();
            }

            if (format == null) {
                format = Rio.getParserFormatForFileName(file.getName());

                if(format == null){
                    throw new IOException();
                }
            }

            repConnect = repository.getConnection();

            String newURI = "com.inovexcorp.myproject." + repositoryID;

            repConnect.add(file, newURI, format);


            System.out.println("Repository set!");
            System.out.println(repConnect.isEmpty());

            System.out.println("Executing Import command");
            System.out.println("Arguments passed: " + repositoryID + " " + file);




            repConnect.close();


        } catch (FileNotFoundException e) {
            System.out.println("FnF Exception!");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("IOException! File type not supported by Sesame.");
            e.printStackTrace();
        } catch (RepositoryException e) {
            System.out.println("Repository Exception!");
            e.printStackTrace();
        } catch (RDFParseException e) {
            System.out.println("RDFParseException! There was an error parsing the RDF file.");
            e.printStackTrace();
        } 


    }


}

CLI-POM:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>parent</artifactId>
        <groupId>org.myproject.cli</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>importer</artifactId>
    <packaging>bundle</packaging>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.karaf.shell</groupId>
            <artifactId>org.apache.karaf.shell.console</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>org.openrdf.sesame</groupId>
            <artifactId>sesame-runtime-osgi</artifactId>
            <version>2.7.14</version>
        </dependency>
        <dependency>
            <groupId>biz.aQute.bnd</groupId>
            <artifactId>bndlib</artifactId>
            <version>2.3.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.openrdf.sesame</groupId>
            <artifactId>sesame-rio-rdfxml</artifactId>
            <version>2.7.14</version>
        </dependency>
        <dependency>
            <groupId>org.openrdf.sesame</groupId>
            <artifactId>sesame-rio-turtle</artifactId>
            <version>2.7.14</version>
        </dependency>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.beust</groupId>
            <artifactId>jcommander</artifactId>
            <version>1.48</version>
        </dependency>

        <dependency>
            <groupId>org.myproject.etl</groupId>
            <artifactId>rdf.import</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>bundle</type>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.3.7</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Import-Package>*</Import-Package>
                        <Export-Package></Export-Package>
                        <Service-Component>*</Service-Component>
                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
            </plugin>


        </plugins>
    </build>

</project>

Import-ServiceImpl pom:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>parent</artifactId>
        <groupId>org.myproject.etl</groupId>
        <version>0.0.1-SNAPSHOT</version>

    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>bundle</packaging>

    <artifactId>rdf.import</artifactId>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.karaf.shell</groupId>
            <artifactId>org.apache.karaf.shell.console</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>org.openrdf.sesame</groupId>
            <artifactId>sesame-runtime-osgi</artifactId>
            <version>2.7.14</version>
        </dependency>
        <dependency>
            <groupId>biz.aQute.bnd</groupId>
            <artifactId>bndlib</artifactId>
            <version>2.3.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.openrdf.sesame</groupId>
            <artifactId>sesame-rio-rdfxml</artifactId>
            <version>2.7.14</version>
        </dependency>
        <dependency>
            <groupId>org.openrdf.sesame</groupId>
            <artifactId>sesame-rio-turtle</artifactId>
            <version>2.7.14</version>
        </dependency>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.beust</groupId>
            <artifactId>jcommander</artifactId>
            <version>1.48</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.3.7</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Import-Package>*</Import-Package>
                        <Export-Package>org.myproject.etl.rdf.importer.api</Export-Package>
                        <Import-Service>org.openrdf.repository.Repository</Import-Service>
                        <Service-Component>*</Service-Component>

                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.parent.build.directory}/index</outputDirectory>
                            <excludeScope>provided</excludeScope>
                        </configuration>
                    </execution>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>${project.artifactId}</artifactId>
                                    <version>${project.version}</version>
                                    <type>jar</type>
                                    <outputDirectory>${project.parent.build.directory}/index</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


        </plugins>
    </build>

</project>

Cli Blueprint.xml:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">

        <command name="myproject/import">
            <action class="org.myproject.cli.importer.CLIImporter" />
        </command>

    </command-bundle>

    <bean id="cliImportService" class="org.myproject.cli.importer.CLIImporter">
        <property name="importService" ref="importServiceBean"/>
    </bean>

    <reference id="importServiceBean"
        interface="org.myproject.etl.rdf.importer.api.RDFImportService"
        availability="mandatory">
    </reference>

</blueprint>

当我在karaf中运行命令时,结果如下:

karaf@root()> myproject:import repoId filepath true
repoId filepath true null
Error executing command: java.lang.NullPointerException

第二行的null是要打印的空服务。另外,这里是日志:显示结果:

java.lang.NullPointerException
    at org.myproject.cli.importer.CLIImporter.doExecute(CLIImporter.java:55)[294:importer:0.0.1.SNAPSHOT]
    at org.apache.karaf.shell.console.AbstractAction.execute(AbstractAction.java:34)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.karaf.shell.console.OsgiCommandSupport.execute(OsgiCommandSupport.java:41)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.karaf.shell.commands.basic.AbstractCommand.execute(AbstractCommand.java:34)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.karaf.shell.compat.CommandTracker$1.execute(CommandTracker.java:109)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.karaf.shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.java:67)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.karaf.shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.java:87)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:480)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:406)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:182)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:119)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:94)[44:org.apache.karaf.shell.core:4.0.1]
    at org.apache.karaf.shell.impl.console.ConsoleSessionImpl.run(ConsoleSessionImpl.java:267)[44:org.apache.karaf.shell.core:4.0.1]
    at java.lang.Thread.run(Thread.java:745)[:1.8.0_60]

1 个答案:

答案 0 :(得分:0)

问题是您在两个地方使用CLIImporter类。一次在命令中,一次在bean中。

因此,您将获得单独的实例。 bean将注入服务,但命令不会。

更改蓝图,如下所示:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">

    <command name="myproject/import">
        <action class="org.myproject.cli.importer.CLIImporter">
            <property name="importService" ref="importServiceBean"/>
        </action>
    </command>

</command-bundle>

<reference id="importServiceBean"
    interface="org.myproject.etl.rdf.importer.api.RDFImportService"
    availability="mandatory">
</reference>