ClassNotFoundException: несоответствие контрольной суммы класса потока

#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. Если вы не хотите, чтобы поле сериализовалось, вы должны объявить его как переходный.