#java #gridgain
#java #gridgain
Вопрос:
Мой удаленный (Linux) и локальный (Windows) узел используют один и тот же jdk версии 1.7.0_45 и gridgain 6.0.3, и загрузка однорангового класса включена. Но я получаю следующее:
Caused by: java.lang.ClassNotFoundException: Optimized stream class checksum mismatch (is same version of marshalled class present on all nodes?) [expected=-3449, actual=7739, cls=class java.io.FileDescriptor]
at org.gridgain.grid.marshaller.optimized.GridOptimizedClassResolver.readClass(GridOptimizedClassResolver.java:345)
Локальная консоль узла имеет журнал:
visor> [20:50:12] Local node's library list differs from remote node's
[20:50:12] <commons-lang-2.6.jar> vs. <not jar or zip file>
[20:50:12] <guava-14.0.1.jar> vs. <guava-15.0.jar>
[20:50:12] <javax.servlet-api-3.0.1.jar> vs. <servlet-api-2.4.jar>
[20:50:12] <jcommander-1.30.jar> vs. <jcommander-1.27.jar>
[20:50:12] <log4j-1.2.16.jar> vs. <log4j.jar>
[20:50:12]
Код
public final class GG_HelloWorld {
public static class GridCmd extends Command<GridEvt> {
@Override
protected void executeImpl() throws CommandException, InterruptedException {
final GridConfiguration config = getEvent().getConfig();
// task
GridComputeTask<String, Integer> task = new GridComputeTaskSplitAdapter<String, Integer>() {
@NotNull
@Override
protected Collection<? extends GridComputeJob> split(int gridSize,
@NotNull String arg) {
Collection<GridComputeJob> jobs = new LinkedList<>();
for (final String word : arg.split(" ")) {
jobs.add(new GridComputeJobAdapter() {
@Nullable
@Override
public Object execute() {
X.println(">>>");
X.println(">>> Printing '" word
"' on this node from grid job.");
X.println(">>>");
// Return number of letters in the word.
return word.length();
}
});
}
return jobs;
}
@Nullable
@Override
public Integer reduce(@NotNull List<GridComputeJobResult> results) {
return results.size() - 1 F.sumInt(F.<Integer>jobResults(results));
}
};
try (Grid g = G.start(config)) {
GridComputeTaskFuture<Integer> fut = g.compute().execute(task, "Hello Grid Enabled World!");
// Wait for task completion.
int phraseLen = fut.get();
X.println(">>>");
X.println(">>> Finished executing Grid "Hello World" example with custom task.");
X.println(">>> Total number of characters in the phrase is '" phraseLen "'.");
X.println(">>> Check all nodes for output (this node is also part of the grid).");
X.println(">>>");
} catch (GridException e) {
throw new CommandException(e);
}
}
}
}
Код, связанный с файлом, вызывается только главным узлом.
Ответ №1:
Похоже, вы пытаетесь (намеренно или нет) отправить java.io.FileDescriptor
сообщение по сети. Я не могу подтвердить это прямо сейчас, но я полагаю, что этот класс может зависеть от платформы, поэтому контрольная сумма не соответствует.
С другой стороны, десериализованный файловый дескриптор в любом случае не будет действителен на удаленном компьютере, поскольку он содержит файловые дескрипторы / дескрипторы операционной системы. Я думаю, что решение здесь состоит в том, чтобы просто убедиться, что экземпляры java.io.FileDescriptor
не отправляются на удаленные узлы.
Если вы отправляете анонимное закрытие вычисления, попробуйте сделать его статическим и передать все необходимые аргументы в качестве параметров конструктора. Таким образом, вы убедитесь, что компилятор java не записывает дополнительные локальные переменные в ваш класс.
Комментарии:
1. сделать его статичным с передачей аргументов решило эту проблему. Теперь он хорошо взаимодействует с удаленным узлом Mac с двумя другими узлами Windows. Я понял, что раздражающие объекты в основном являются внутренними классами, которые отслеживают родительский и, следовательно, связаны с родительским путем к классу. Таким образом, все объекты, подключенные к родительскому, пересылались. Статическое разделение его.
Ответ №2:
Кроме того, если вы сохраняете FileDescriptor в одном из передаваемых вами классов, вы можете объявить его как transient
удаленный узел и повторно инициализировать его всякий раз, когда к нему обращаются.
Комментарии:
1. но разве код, связанный с JDK, не должен быть получен с локального узла? зачем отправлять его через?
2. @Susanta Вот как работает сериализация Java. Если вы не хотите, чтобы поле сериализовалось, вы должны объявить его как переходный.