使用库的Java项目在使用使用相同库的项目时会抛出NoClassDefFoundError

时间:2014-03-31 16:38:34

标签: java eclipse repast-simphony

我正在创建一个Java库,以便在其他Java项目中使用。项目使用Repast Symphony,我的库也这样做(所以我担心这个错误是由一些冲突引起的)。一切都很好,但是当我运行Repast模拟时,它会抛出java.lang.NoClassDefFoundError: repast/simphony/context/Context

我尝试将我的库导出为jar,直接导入项目并将库添加到我项目的类路径中,但无济于事。我能做错什么?

这个Context类正在我的库和我的项目中使用。以下是它在两个类中使用的片段:

// MyContextBulder.java
// This file is in my project
// This class is called by Repast first
import repast.simphony.context.Context;
import repast.simphony.dataLoader.ContextBuilder;
import mylibrary.core.DF;
import mylibrary.core.DF.MyContext;

public class MyContextBuilder implements ContextBuilder<Object> {

    @Override
    public Context<Object> build(Context<Object> context) {

        context.setId("test");
        DF.setContext((MyContext) context);

        // Create agent
        new MyAgent();
        // Add the agent to the Repast context.
        // context.add(t);

        return context;
    }
}
// DF.java
// This file is in my library

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.commons.collections15.Predicate;

import repast.simphony.context.Context;
import repast.simphony.context.ContextListener;
import repast.simphony.space.projection.Projection;
import repast.simphony.util.collections.IndexedIterable;
import repast.simphony.valueLayer.ValueLayer;
import mylibrary.Agent;


/**
 * This static class provides the Directory Facilitator Service
 * and is used to send messages to agents
 * and to keep a directory of all agents in the application.
 * Agents use the static method send(ACLMessage) to send a message
 * to one or more agents. The ACLMessage object contains
 * the receiver agent and the sender (so the receiver can reply back).
 * 
 * This class needs to be setup initially before registering new agents.
 * To do that, simply call setContext(...);
 * @author joaolopes
 *
 */
public class DF {

    private static int lastAID = 0; // Just to help generate new identifiers
    private static HashMap<Integer, Agent> agents; // Contains all agents

    /**
     * The Repast context that contains all
     * scheduled Repast objects.
     */
    private static MyContext context = null;

    /**
     * Registers the agent in the directory and returns its
     * AID (freshly generated for it). If the agent is already
     * registered, returns its current AID.
     * @param agent The agent to be registered
     * @return The AID generated for the agent.
     */
    public static int registerAgent(Agent agent) {
        // If this agent is already in the hashMap,
        // just return its key.
        if (getAgents().containsValue(agent)) {
            return agent.getAID();
        }

        // Quick way to find a new ID for this agent
        // that is not in use at the moment.
        while (getAgents().containsKey(lastAID)) {
            lastAID++;
        }

        // The agent must know their own ID.
        agent.setAID(lastAID);
        agents.put(lastAID, agent);
        System.err.println(context.toString());
        context.add(agent);
        return lastAID;
    }

    public static void setContext(MyContext c){
        context = c;
    }
}

编辑以添加评论中的相关信息: 我不像在库中那样直接在项目中导入repast JAR。 Repast Symphony作为插件安装在Eclipse中,因此我创建了#34; Repast Projects&#34;包括所有Repast库。因此,我无法删除导致类可能冲突的特定JAR。

2 个答案:

答案 0 :(得分:2)

正如你所说的那样。这个错误应该是jar中相同类之间的冲突。如果您使用的是IDE,请尝试清理构建并重新构建。

而且我建议你只使用一个交响乐库jar。多个类定义总是会导致JVM类加载器的歧义。

尽量不要在导入项目中使用symphony jar,因为您已经在导出的jar中使用了它。导入lib后,应该没有错误。

试试这个,让我知道它是怎么回事。

我建议您使用构建工具。像Maven这样的东西。然后使用正确的插件maven将为您解决此问题。您需要做的就是告诉Maven您需要一个特定的jar文件。然后会出现一个魔法,你将有一个运行良好的jar文件来分发

答案 1 :(得分:1)

当JVM尝试运行应用程序时抛出java.lang.NoClassDefFoundError。典型的情况是你有一个jar文件作为“接口”。然后你得到了其他实现该接口的jar文件。

所以你需要做的是,在你的jar类路径中有Repast jar。这样你的程序就可以找到你想要使用的正确的类。

相关问题