SBT: исключить класс из Jar - PullRequest
13 голосов
/ 19 октября 2011

Я конвертирую устаревший проект jar в SBT, и по странным причинам, которые нелегко решить, этот проект поставляется с " javax / servlet / Servlet.class " внутри него.Поэтому мне нужно как-то исключить этот класс из файла jar, сгенерированного package-bin .Как мне это сделать?Желательно исключить использование подстановочного знака (т. Е. javax. *).

Плагин сборки SBT выглядит так, как будто у него есть функции, которые это сделают, но я беспокоюсь, что использование sbt assembly означает, что мой проект jar не будет работать в проекте с несколькими модулямит.е. если я включу его в качестве зависимости в файл войны, тогда нужно будет указать, что военным проектам нужно запускать assembly в зависимом проекте jar, а не package-bin - но я могу бытьздесь ошиблись).

Ответы [ 2 ]

15 голосов
/ 23 октября 2011

Каждая задача объявляет другие задачи и параметры, которые она использует.Вы можете использовать inspect для определения этих входных данных, как описано в Проверка настроек и в недавнем посте в блоге Джона Ченга .

соответствующая задача, используемая packageBin, равна mappings.Задача mappings собирает файлы для включения в банку и сопоставляет их с путем в банке.Некоторый фон объясняется в Файлы сопоставления , но в результате mappings выдает значение типа Seq[(File, String)].Здесь File - это входной файл, предоставляющий содержимое, а String - путь в jar.

Итак, чтобы изменить сопоставления для задачи packageBin, отфильтруйте пути из сопоставлений по умолчанию, которые вы используете.не нужно включать:

mappings in (Compile,packageBin) ~= { (ms: Seq[(File, String)]) =>
  ms filter { case (file, toPath) =>
    toPath != "javax/servlet/Servlet.class"
  }
}

mappings in (Compile,packageBin) выбирает сопоставления для основной задачи пакета (в отличие от источников тестирования или задачи packageSrc).

x ~= f означает "установить x в результате применения функции f к предыдущему значению x ".(Подробнее см. Подробнее о настройках .)

Фильтр отбрасывает все пары, где путь соответствует классу сервлета.

2 голосов
/ 20 октября 2011

Я придумал это решение, оно определяет новую задачу компиляции, которая зависит от предыдущей задачи компиляции (таким образом, эффективно позволяя мне подключиться сразу после компиляции исходного кода и перед его упаковкой)

def mySettings = {
  // add functionality to the standard compile task 
  inConfig(Compile)(Seq(compile in Compile <<= (target,streams,compile in Compile) map{
    (targetDirectory, taskStream, analysis) =>
      import taskStream.log
      // this runs after compile but before package-bin
      recursiveListFiles(targetDirectory, ".*javax.*".r) foreach { 
        file =>
          log.warn("deleting matched resource: " + file.getAbsolutePath())
          IO.delete(file)
      }
      analysis
    })) ++
    Seq(name := "MyProject", version := "1.0", exportJars := true)
}

def recursiveListFiles(f: File, r: Regex): Array[File] = {
  val these = f.listFiles
  val good = these.filter(f => r.findFirstIn(f.getName).isDefined)
  good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_, r))
}

Это немного сложнее, чем я надеялся, но оно позволяет мне делать всевозможные модификации перед упаковкой (в этом случае поиск в целевой папке удаляет все файлы классов, которые соответствуют регулярному выражению).Также он выполнил мою вторую цель - придерживаться стандартного жизненного цикла SBT.

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