Такая проблема уже давно меня беспокоит, поэтому мне было любопытно, как вы подходите к решению следующей ситуации:
Представьте, что у меня есть два разных проекта Eclipse в одной рабочей области под названием ProjectA и ProjectB. ProjectB содержит в своем корневом каталоге .exe-файл, который вызывается из ProjectA следующим образом:
Process p = Runtime.getRuntime().exec( "../ProjectB/ProjectB.exe" );
Проблема в том, что после развертывания структура немного меняется: ProjectA теперь является .jar. Рядом с этим jar теперь находится папка с ProjectB, которая содержит ProjectB с его файлами .exe, .jars и так далее. Теперь правильный вызов должен выглядеть следующим образом:
Process p = Runtime.getRuntime().exec( "ProjectB/ProjectB.exe" );
Поскольку мне нужно, чтобы эти структуры оставались такими, как есть, и я не хочу, чтобы в моем приложении для каждого случая было два разных вызова .exec, я попробовал несколько способов обойти эту ситуацию:
1) Добавление ProjectB в качестве ClassFolder в ProjectA и предоставление возможности ContextClassLoader выяснить, где найти ProjectB.exe следующим образом:
URL url= Thread.currentThread().getContextClassLoader().getResource( "ProjectB.exe" );
file = new File( url.toURI() );
Process p = Runtime.getRuntime().exec( file.getAbsolutePath() );
Это решение прекрасно работало, пока я не попытался развернуть свое приложение на сетевом диске.
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: URI has an authority component
at java.io.File.<init>(Unknown Source)
2) Поскольку мне не разрешено создавать сетевой диск для каждого клиента, я попытался обойти эту проблему и сделал следующее:
URL url= Thread.currentThread().getContextClassLoader().getResource( "ProjectB.exe" );
File file = new File( url.getFile() );
Process p = Runtime.getRuntime().exec( file.getAbsolutePath() );
Это казалось многообещающим, но, к сожалению, до тех пор, пока мой путь оставался без черточек (""), поскольку этот appraoch, казалось, преобразовывал каждую черточку в "% 20", что на самом деле не похоже, что runtimeexecutor не нравится. Конечно, после этого я мог бы заменить каждый "% 20" на "", но мне это кажется немного хакерским.
Другое требование состоит в том, что оба приложения должны работать в другой JVM, поэтому я называю .exe-файл методом Runtimeexecution. Итак, мой последний вопрос: есть ли способ очистить вызовы ProjectB без каких-либо обходных путей?