Karaf 4.0.1 中声明式服务的空服务问题
Issue with null service with Declarative Services in Karaf 4.0.1
我正在尝试创建可部署在 karaf 上的服务,该服务将文件导入存储库。我的项目设置方式是我有一个命令行 class 来处理 karaf 中命令的创建(通过使用 org.apache.felix.gogo.commands 注释和 blueprint.xml 文件)和调用服务,以及一个单独的项目来处理服务的实施。
命令是在 karaf 中创建的,没有问题,我可以用相应的参数调用它,但是由于导入服务为空,所以在 运行 连接它时我总是得到一个空指针异常。 运行 scr:details 关于导入服务和存储库 returns 此信息:
**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 和服务实施包的 headers:
**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 class:
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 class:
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
第二行的空是打印出来的空服务。此外,这是 log:display 结果:
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.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]
问题是您在两个地方使用了 class 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>
我正在尝试创建可部署在 karaf 上的服务,该服务将文件导入存储库。我的项目设置方式是我有一个命令行 class 来处理 karaf 中命令的创建(通过使用 org.apache.felix.gogo.commands 注释和 blueprint.xml 文件)和调用服务,以及一个单独的项目来处理服务的实施。
命令是在 karaf 中创建的,没有问题,我可以用相应的参数调用它,但是由于导入服务为空,所以在 运行 连接它时我总是得到一个空指针异常。 运行 scr:details 关于导入服务和存储库 returns 此信息:
**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 和服务实施包的 headers:
**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 class:
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 class:
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
第二行的空是打印出来的空服务。此外,这是 log:display 结果:
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.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]
问题是您在两个地方使用了 class 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>