1

I have a problem getting BioJava to work in a Netbeans RCP application, built using Maven. I've created a Maven module as a wrapper, including org.biojava.* and org.forester.* packages as public in the POM. Then, from another module I set the wrapper as a dependency, and use some of the basic examples from the BioJava cookbook for testing.

Whenever I try to instantiate some object of a class from BioJava, the application freezes and I have to kill it using the Windows task manager.

Here's the wrapper's pom file:

    <?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>
    <parent>
        <groupId>nl.hecklab.bioinformatics</groupId>
        <artifactId>Spider-parent</artifactId>
        <version>1.0.0</version>
    </parent>
    <artifactId>BiojavaWrapper</artifactId>
    <version>4.1.0</version>
    <packaging>nbm</packaging>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>nbm-maven-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <useOSGiDependencies>true</useOSGiDependencies>
                    <publicPackages>
                        <publicPackage>org.biojava.*</publicPackage>
                        <publicPackage>org.forester.*</publicPackage>
                    </publicPackages>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <useDefaultManifestFile>true</useDefaultManifestFile>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.biojava</groupId>
            <artifactId>biojava-alignment</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

Here's some code I try to get to work. This is just a very coarse example, called from a button in a TopComponent. Input and output are just text fields.

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

    Reader r = new Reader(new File("D:\\current\\fastafile.fasta"));
    for (ProteinSequence a : r.getSequences()) {
        input.append(a.toString());
    }
    Profile<ProteinSequence, AminoAcidCompound> profile = Alignments.getMultipleSequenceAlignment(r.sequences);
    output.setText(String.format("Clustalw:%n%s%n", profile));

    ConcurrencyTools.shutdown();


}     

Here's the reader class:

public class Reader {

    List<ProteinSequence> sequences = new ArrayList<>();

    public Reader(File fastaFile) {

        try {

            FileInputStream inStream = new FileInputStream(fastaFile);
            FastaReader<ProteinSequence, AminoAcidCompound> fastaReader
                    = new FastaReader<>(
                            inStream,
                            new GenericFastaHeaderParser<ProteinSequence, AminoAcidCompound>(),
                            new ProteinSequenceCreator(AminoAcidCompoundSet.getAminoAcidCompoundSet()));
            LinkedHashMap<String, ProteinSequence> b = fastaReader.process();

            sequences.addAll(b.values());
        } catch (IOException ex) {
            Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public List<ProteinSequence> getSequences() {
        return sequences;
    }

}

In the (Netbeans) IDE, the classes are found and used in autocompletion, and the project builds successfully, in each case indicating that principally the dependencies are set up correctly.

  • Hi Henk, you should post some of the code your using, try to get a minimal example which has the bug. This way people can help if they happen to have experience. – Jaap Nov 02 '15 at 14:11
  • That's a great idea, Jaap, you're right. Sorry for my lazyness. – Henk van den Toorn Nov 02 '15 at 14:29
  • I'm sorry I can't help you, I don't know a lot about maven, netbeans or biojava... – Jaap Nov 02 '15 at 15:24
  • I've done a lot of tracing, and found the program freezes when running the constructor (or, as I went through reflection to debug it, inside the `ConstructorAccessor` when the `Constructor` `.getInstance(*)` is called). I'm still very confused about this... – Henk van den Toorn Nov 10 '15 at 12:21

2 Answers2

0

First of all check the wrapper module's manifest to see if all entries are correctly generated, especially since you define useOSGiDependencies==true. It could be that the biojava jars contain osgi headers and then you are not wrapping the jars in module, but declare a dependency on osgi plugin.

However locking of the app is weird, if there was something wrong with the runtime dependencies I would have expected an early 'unsatisfied dependencies' error. You might want to create a thread dump and check what's going on. Maybe you have a deadlock. Or since your action (jButton1ActionPerformed) is called from AWT, maybe the whole reading thing just takes time and your UI thread is locked.

mkleint
  • 2,281
  • 1
  • 14
  • 17
  • Thanks for responding, I'll have a look. Biojava requires slf4j which does have osgi headers. Unfortunately, I'm not completely clear on when to use a module as osgi or just as a jar. I've tried switching the osgidependencies off, but this does not seem to make a difference other than that the wrapper won't compile. Setting to 'on' makes the module compile once more. Slowness: I've tried to perform the same code in a regular swing app, and it works (indeed locking the gui) but in a regular time frame. When debugging, it seems everything locks up when I try to instantiate an object. – Henk van den Toorn Nov 04 '15 at 12:22
0

I've done a lot of searching and found that the actual culprit is slf4j, that's used throughout BioJava. I don't know why it freezes the platform application, but I'm able to cause my module to not install by creating a slf4j logger in it. I've seen a solution online for a wrapper module, and it turns out it's enough to create a wrapper for org.slf4j:slf4j-api:x.y.z together with org.slf4j:slf4j-jdk14:x.y.z. Add org.slf4j.* to the public packages. Here's the POM:

<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>
<parent>
    <groupId>group</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0.0</version>
</parent>
<artifactId>slf4jwrapper</artifactId>
<packaging>nbm</packaging>
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>nbm-maven-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <publicPackages>
                    <publicPackage>org.slf4j.*</publicPackage>
                </publicPackages>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <useDefaultManifestFile>true</useDefaultManifestFile>
            </configuration>
        </plugin>
    </plugins>
</build>
<dependencies>
    <dependency>
        <groupId>org.netbeans.api</groupId>
        <artifactId>org-netbeans-api-annotations-common</artifactId>
        <version>${netbeans.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.7.7</version>
    </dependency>
</dependencies>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

The wrapper should then be used in the BioJava dependent modules, but it should work for other modules depending on slf4j as well.