0
votes

I'm trying to read indexes of solr version 4 with application that I wrote in Java, I Added this dependencies to my ivy.xml file:

<dependency org="org.apache.lucene" name="lucene-core" rev="5.2.1">

</dependency>
<dependency org="org.apache.hadoop" name="hadoop-hdfs" rev="2.7.1"/>
<dependency org="org.slf4j" name="slf4j-jdk14" rev="1.7.7"/>
<dependency org="log4j" name="log4j" rev="1.2.17"/>
<dependency org="org.apache.lucene" name="lucene-backward-codecs" rev="5.2.1"/>

I created the jar file of my application, when I want to run the application, it give me this errors:

java.lang.IllegalArgumentException: Could not load codec 'Lucene410'.  Did you forget to add lucene-backward-codecs.jar?

and

Caused by: java.lang.IllegalArgumentException: An SPI class of type org.apache.lucene.codecs.Codec with name 'Lucene410' does not exist.  You need to add the corresponding JAR file supporting this SPI to your classpath.  The current classpath supports the following names: [Lucene50]

I used this line of code:

System.out.println("codec path:" + Lucene410Codec.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

and it give me the path to jar file of codec jar ,so it exists.

update: also, in eclipse, I can use this line of code:

Codec.availableCodecs()

and it gives me the list of codecs and lucene410 codec shows up in the list, but not when I try to run the jar file.

I read somewhere that I should add service for this codec jar file to my build.xml, but it doesn't work,this is my jar part in ant(build.xml):

<target name="jar" depends="compile" description="Creates the JAR file with a Main-Class.">
    <mkdir dir="${jar.dir}" />
    <copy file="conf/log4j.properties" todir="${classes.dir}" />

    <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
        <exclude name="**/org.apache.lucene.codecs.Codec"/>
        <zipgroupfileset dir="lib" includes="*.jar" />
        <manifest>
            <attribute name="Main-Class" value="${Main-Class}" />
            <attribute name="Class-Path" value=". ${jar.classpath}" />
        </manifest>
        <service type="org.apache.lucene.codecs.Codec">
            <provider classname="org.apache.lucene.codecs.lucene40.Lucene40Codec" />
            <provider classname="org.apache.lucene.codecs.lucene41.Lucene41Codec" />
            <provider classname="org.apache.lucene.codecs.lucene42.Lucene42Codec" />
            <provider classname="org.apache.lucene.codecs.lucene45.Lucene45Codec" />
            <provider classname="org.apache.lucene.codecs.lucene46.Lucene46Codec" />
            <provider classname="org.apache.lucene.codecs.lucene49.Lucene49Codec" />
            <provider classname="org.apache.lucene.codecs.lucene410.Lucene410Codec" />
            <provider classname="org.apache.lucene.codecs.lucene50.Lucene50Codec" />
        </service>  
    </jar>
</target>

and this is the class.path that I used to add jar files inside my lib folder to classpath:

<path id="class.path">
    <fileset dir="lib">
        <include name="**/*.jar" />
    </fileset>

The problem is that the lucene-core package has it own "org.apache.lucene.codecs.Codec" file in META-INF/services and that overrides the one that I am trying to create in the 'service' section of the jar target in build file. exclude tag that can be seen in build.xml does not work, neither does the exclude property on zipgroupfileset. Any help would be really appreciated.

2
Are you launching the java program from ANT? If so how is the classpath being set for the Java task?Mark O'Connor
@MarkO'Connor yes I use ant and I added the Java task part to my question.Ladan Nekuii
I think you should stop trying to repackage the 3rd party jars. Try creating an executable jar with an embedded classpath, as I've suggested below.Mark O'Connor

2 Answers

1
votes

I might be a little late. But all I had to do is add lucene-backward-codecs.jar as external jar file which can be found in the Downloaded zip file.

0
votes

Not sure what the problem is. You could try the following, create a jar with it's dependencies on a classpath.

<target name="jar" depends="compile" description="Creates the JAR file with a Main-Class.">
    <mkdir dir="${jar.dir}" />
    <copy file="conf/log4j.properties" todir="${classes.dir}" />

    <!-- Copy dependencies into the distribution directory -->
    <ivy:retrieve pattern="${jar.dir}/[artifact]-[revision](-[classifier]).[ext]"/>

    <!-- Create a manifest classpath property -->
    <manifestclasspath property="jar.classpath" jarfile="${jar.dir}/${ant.project.name}.jar">
       <classpath>
          <fileset dir="${jar.dir}" includes="*.jar"/>
       </classpath>
    </manifestclasspath>

    <!-- Create an executable jar -->
    <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
        <manifest>
            <attribute name="Main-Class" value="${Main-Class}" />
            <attribute name="Class-Path" value="${jar.classpath}" />
        </manifest>
    </jar>
</target>