gpt4 book ai didi

java - Android 上的 Lucene 4 错误

转载 作者:搜寻专家 更新时间:2023-11-01 08:52:23 27 4
gpt4 key购买 nike

在将 Lucene 4 与 Android API 19 (4.4.2) 结合使用时,我遇到了这个错误。

Caused by: java.lang.IllegalArgumentException: A SPI class of type org.apache.lucene.codecs.Codec with name 'Lucene46' does not exist. You need to add the corresponding JAR file supporting this SPI to your classpath.The current classpath supports the following names: []
at org.apache.lucene.util.NamedSPILoader.lookup(NamedSPILoader.java:109)
at org.apache.lucene.codecs.Codec.forName(Codec.java:95)
at org.apache.lucene.codecs.Codec.<clinit>(Codec.java:122) at org.apache.lucene.index.LiveIndexWriterConfig.<init>(LiveIndexWriterConfig.java:122) at org.apache.lucene.index.IndexWriterConfig.<init>(IndexWriterConfig.java:165)

这与 https://stackoverflow.com/questions/18944634/running-lucene-4-4-on-android 报告的错误类似

我迁移到 IntelliJ 上的 android-maven-plugin,因为它是我的问题的建议解决方案,但我仍然遇到问题。这是我的 Maven pom.xml

<?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">
<modelVersion>4.0.0</modelVersion>

<groupId>com.johnbohne.chishiki</groupId>
<artifactId>Chishiki</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>jar</packaging>

<name>Chishiki</name>
<build>
<sourceDirectory>src</sourceDirectory>
<finalName>${project.artifactId}</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.8.2</version>
<extensions>true</extensions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version>
<configuration>
<source>1.5</source><target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>

我知道可以在 Android 上使用 Lucene 3.0,但我不太确定 Lucene 4.0。有谁知道如何让 Lucene 4.0 在 Android 中工作?

最佳答案

这是一种运行它的方法(这肯定不是最好的解决方案,但它有效):

  1. 从 lucene-core 中删除 org/apache/lucene/util/SPIClassIterator
  2. 将打过补丁的版本放到源代码树中
  3. 将 META-INF/services 文件添加到您的 Assets 文件夹
  4. 手动合并重复的服务文件

我正在使用以下(已打补丁的)版本

package org.apache.lucene.util;

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.ServiceConfigurationError;

/**
* Helper class for loading SPI classes from classpath (META-INF files).
* This is a light impl of {@link java.util.ServiceLoader} but is guaranteed to
* be bug-free regarding classpath order and does not instantiate or initialize
* the classes found.
*
* @lucene.internal
*/
public final class SPIClassIterator<S> implements Iterator<Class<? extends S>> {
private static final String META_INF_SERVICES = "/assets/META-INF/services/";

private final Class<S> clazz;
private final ClassLoader loader;
private final Enumeration<URL> profilesEnum;
private Iterator<String> linesIterator;

public static <S> SPIClassIterator<S> get(Class<S> clazz) {
return new SPIClassIterator<S>(clazz, Thread.currentThread().getContextClassLoader());
}

public static <S> SPIClassIterator<S> get(Class<S> clazz, ClassLoader loader) {
return new SPIClassIterator<S>(clazz, loader);
}

/** Utility method to check if some class loader is a (grand-)parent of or the same as another one.
* This means the child will be able to load all classes from the parent, too. */
public static boolean isParentClassLoader(final ClassLoader parent, ClassLoader child) {
while (child != null) {
if (child == parent) {
return true;
}
child = child.getParent();
}
return false;
}

private SPIClassIterator(Class<S> clazz, ClassLoader loader) {
this.clazz = clazz;
final String fullName = META_INF_SERVICES + clazz.getName();
this.profilesEnum =
Collections.enumeration(
Arrays.asList(new URL[]{getClass().getResource(fullName)}));
this.loader = (loader == null) ? ClassLoader.getSystemClassLoader() : loader;
this.linesIterator = Collections.<String>emptySet().iterator();
}

private boolean loadNextProfile() {
ArrayList<String> lines = null;
while (profilesEnum.hasMoreElements()) {
if (lines != null) {
lines.clear();
} else {
lines = new ArrayList<String>();
}
final URL url = profilesEnum.nextElement();
try {
final InputStream in = url.openStream();
IOException priorE = null;
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
final int pos = line.indexOf('#');
if (pos >= 0) {
line = line.substring(0, pos);
}
line = line.trim();
if (line.length() > 0) {
lines.add(line);
}
}
} catch (IOException ioe) {
priorE = ioe;
} finally {
IOUtils.closeWhileHandlingException(priorE, in);
}
} catch (IOException ioe) {
throw new ServiceConfigurationError("Error loading SPI class list from URL: " + url, ioe);
}
if (!lines.isEmpty()) {
this.linesIterator = lines.iterator();
return true;
}
}
return false;
}

@Override
public boolean hasNext() {
return linesIterator.hasNext() || loadNextProfile();
}

@Override
public Class<? extends S> next() {
// hasNext() implicitely loads the next profile, so it is essential to call this here!
if (!hasNext()) {
throw new NoSuchElementException();
}
assert linesIterator.hasNext();
final String c = linesIterator.next();
try {
// don't initialize the class (pass false as 2nd parameter):
return Class.forName(c, false, loader).asSubclass(clazz);
} catch (ClassNotFoundException cnfe) {
throw new ServiceConfigurationError(String.format(Locale.ROOT, "A SPI class of type %s with classname %s does not exist, "+
"please fix the file '%s%1$s' in your classpath.", clazz.getName(), c, META_INF_SERVICES));
}
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}

}

所需的更改?

  1. META_INF_SERVICES 指向/assets/META-INF/services/而不是 META-INF/services/
  2. 构造函数不同

编辑:这是针对 lucene 4.7.1 的。我现在确定它可以创建一个空目录,我不确定索引是否完全有效。

编辑 2:我现在可以确认它确实有效。至少手动查询创建和索引创建按预期工作。

编辑 3:我刚刚基于此完成了自己的联系人合并。源代码位于 github/rtreffer/ContactMerger。如果你有兴趣。

编辑 4:我现在可以在没有修补 jar 的情况下进行构建。我只是将 SPI 加载器放在 src 文件夹中,禁用库预索引,让 dx 完成它的工作。它速度较慢,但​​ src/classes 实现胜出,我可以从 maven central 中提取所有依赖项。查看build.gradle了解详情。

关于java - Android 上的 Lucene 4 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21951049/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com