我正在尝试创建一个可部署在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]
答案 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>