Я создаю библиотеку Java для использования в других проектах Java. В проектах используется Repast Symphony, и моя библиотека тоже делает это (так что я боюсь, что эта ошибка вызвана некоторым конфликтом). Все строит отлично, но когда я запускаю симуляцию Repast, он бросает java.lang.NoClassDefFoundError: repast/simphony/context/Context
Я попытался экспортировать свою библиотеку в виде банки, импортируя проект напрямую и добавляя библиотеку в свой путь к классу проекта, но безрезультатно. Что я могу делать неправильно?
Этот класс 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;
}
}
Редактирование, чтобы добавить соответствующую информацию из комментариев: я не импортирую Jast repast прямо в мои проекты, как в моей библиотеке. Repast Symphony установлена в Eclipse как плагин, поэтому я создал "Проекты Repast", которые включают в себя все библиотеки Repast. Поэтому я не могу удалить конкретный JAR, который вызывает возможный конфликт классов.
Как вы сказали. Эта ошибка должна быть конфликтом между теми же классами в банке. Если вы используете IDE, попробуйте снова очистить сборку и перестроить.
А также я предлагаю вам использовать только одну библиотеку симфонической библиотеки. Множественные определения классов всегда приводят к двусмысленности для загрузчика классов JVM.
Старайтесь не использовать симфоническую банку в проекте импорта, поскольку у вас уже есть ее в экспортированной банке. После импорта вашей библиотеки ошибок не должно быть.
Попробуйте это и дайте мне знать, как это происходит.
Я предлагаю вам использовать инструмент построения. Что-то вроде Maven. Тогда maven с правильным плагином исправит эту проблему для вас. Все, что вам нужно сделать, это сказать Maven, что вам нужен конкретный файл jar. Затем произойдет волшебство, и у вас будет хорошо работающий файл jar для распространения
java.lang.NoClassDefFoundError вызывается, когда JVM пытается запустить приложение. Типичные случаи - когда вы получили один jar файл как "интерфейс". Затем вы получите другой jar файл, который реализует этот интерфейс.
Итак, что вам нужно сделать, это то, что у вас есть баня Repast внутри вашего пути класса jars. Чтобы ваша программа могла найти нужный класс, который вы хотите использовать.