Проект работает в затмении, но не при экспорте - PullRequest
0 голосов
/ 09 июня 2010

Я написал приложение, которое использует GraphViz для генерации некоторых графиков в формате .gif в соответствии с синтаксисом DOT. Когда я запускаю из Eclipse, изображения генерируются нормально, но когда я экспортирую его как банку, изображения создаются, но в них нет данных. Когда я смотрю их в Microsoft Picture Viewer, это просто красный X.

Это работало как экспортированная банка, пока я не поместил генерацию изображения в его собственный поток. Я не могу понять, что здесь происходит. Есть ли проблемы с экспортом многопоточных проектов? У кого-нибудь есть идеи?

Спасибо

Вот часть кода. Трудно точно определить, что идет не так.

/**
* Writes the graph's image in a file.
* @param img   A byte array containing the image of the graph.
* @param to    A File object to where we want to write.
* @return Success: 1, Failure: -1
*/

public int writeGraphToFile(byte[] img, File to)
   {
      try {
         FileOutputStream fos = new FileOutputStream(to);
         fos.write(img);
         fos.close();
      } catch (java.io.IOException ioe) { return -1; }
      return 1;
   }

Вышеуказанная функция вызывается из альтернативного потока этим вызовом.

public void generateMainGraph() {
        //create the graph and put it to file name mainGraphCount.gif
        GraphViz gv = new GraphViz();
        System.out.println("Generating MAIN graph...");

        //add the ending } to mainDot
        mainDot += "}";

        File newGraph = new File("graphs\\main" + Integer.toString(mainGraphCount) + ".gif");
        gv.writeGraphToFile(gv.getGraph(mainDot), newGraph);
}

Вот поток, который вызывает функцию, которая вызывает метод generateMainGraph (...).

graphGeneratingThread = new Runnable() {
            //This method will run in the timer thread
            public void run() {
                try {
                    //Generate the graphs
                    if (iData.importDataSet()) {
                        int timeout = 0;
                        Scanner scan = new Scanner(graphGen.logSource);
                        while(timeout < 10) {
                            if(!scan.hasNextLine()) {
                                Thread.sleep(1000);
                                timeout++;
                            } else {
                                timeout = 0;
                                graphGen.generateGraph(scan.nextLine());   //This function calls generateMainGraph(...)
                                if(!beginningButton.isEnabled()) {
                                    enableTivoButtons();
                                }
                            }
                        }
                    }
                } catch(Exception exc) {
                    System.err.println("GraphGenerationThread Runnable Error: " + exc.getMessage() + "\n");
                    exc.printStackTrace();
                    System.exit(1);
                }
            }
        };

Ответы [ 2 ]

1 голос
/ 10 июня 2010

Не имеет значения, является ли проект многопоточным или нет при экспорте. Различия вызваны тем, как виртуальные машины планируют потоки (на что может повлиять запуск в eclipse).

Так как ваша проблема связана с многопоточной версией, я предполагаю, что у вас есть внутреннее состояние объекта, которое повреждено в середине операции одного потока другим потоком. Например:

  1. Нить A генерирует данные изображения
  2. Поток B заменяет массив данных пустым
  3. Поток A записывает данные (которые теперь пусты с шага 2)

это будет объяснение для 0-байтового изображения. Другой сценарий:

  1. Поток A начинает генерировать данные изображения
  2. Поток B начинает генерировать данные изображения
  3. Поток A завершает генерацию данных.
  4. Поток A записывает данные изображения (которые теперь содержат часть данных потока B)

Это может привести к повреждению файла изображения. Отладка параллельного кода может быть сложно. Мое предложение:

  1. Найдите любой код, который может быть вызван несколькими потоками одновременно.
  2. Добавьте операторы ведения журнала, включая Thread.currentThread (). GetName (), если он еще не является частью используемого вами API ведения журнала.
  3. Посмотрите на чередование двух потоков, это должно дать вам представление о том, где данные могут быть повреждены.

Если вы ищете «простое решение» после того, как найдете код, который может быть запущен несколькими потоками одновременно, и эффект ваших данных просто синхронизирует этот метод, однако это, скорее всего, потерпит неудачу при добавлении Темы.

1 голос
/ 09 июня 2010

Проверьте путь к классам в Eclipse.Скорее всего, вам не хватает кувшина на вашем пути за пределами Затмения.Вы можете перечислить необходимые банки в Манифесте вашей банки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...