BlackBerry: создайте COD из исходного файла JAR в скрипте Ant

Как мне использовать Ant (бб-муравей-инструменты) чтобыcompile a JAR file into a COD? то есть без других исходных файлов

Reason

В конечном итоге мне нужен скрипт, который будет работатьДжар Джар Линкс (jarjar) во время сборки, чтобы обойти проблемы пространства имен при использовании нашего SDK в нескольких приложениях. Jarjar принимает файл JAR в качестве входных данных, и я предполагаю, что он выводит файл JAR.

Итак, чтобы запустить jarjar в сборке bb-ant-tools, мне нужно знатьhow to compile that output JAR into a COD.

Я сосредотачиваюсь только на этой части проблемы, чтобы минимизировать другие возможные источники ошибок. Я попытаюсь сделать шаг jarjar, когда смогу освоить встраивание JAR в COD.

Progress

1) Я могу встроить свой проект в работающую ХПК, подписать и запустить на устройстве.

2) Чтобы включить код SDK, я в настоящее время добавляю исходные папки в основную сборку проекта. (В будущем я хотел бы знать, как включить библиотеку в сборку как JAR -BlackBerry - Ant скрипт для включения JAR в проект без внешних зависимостей)

3) Вывод этого шага включает в себя обычные файлы:

MyApp.cod (if I sign this, it runs perfectly on device) MyApp.csl MyApp.cso MyApp.debug MyApp.jad MyApp.jar (I want to run jarjar on this) MyApp.rapc

4) Я попытался запустить 2-ю сборку, взяв вышеуказанный JAR-файл и используя его как единственный исходный файл вrapc вызов. Я делаю это, указывая наsrc тегrapc в папке, содержащей только мой файл JAR.

В заключительной части сборки, когда Rapcadding файлы, я получаю сообщение об ошибке:

 java.util.zip.ZipException: duplicate entry: MyApp-1.cod

(full details of error below in edited build output)

Я вижу, что это2nd time that rapc tries to add this file, Я не понимаю, почему, поскольку в JAR есть только одна копия этого файла.

Build Output (edited with ...etc to make it readable )
build:
    [mkdir] Skipping C:\development\ant\new_test\MyApp\build because it already exists.
     [copy] Copying 1 file to C:\development\ant\new_test\MyApp\build
     [copy] Copying C:\development\ant\new_test\MyApp\icon.png to C:\development\ant\new_test\MyApp\build\icon.png
     [rapc] Compiling 1 source files to MyApp.cod
     [rapc] Executing 'C:\Java\jdk1.6.0_24\jre\bin\java.exe' with arguments:
     [rapc] '-classpath'
     [rapc] 'C:\Java\jdk1.6.0_24\lib\tools.jar;C:\development\tools\bb-jde\jde5.0\components\bin\rapc.jar'
     [rapc] 'net.rim.tools.compiler.Compiler'
     [rapc] '-verbose'
     [rapc] 'import=C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar'
     [rapc] 'codename=MyApp'
     [rapc] 'MyApp.rapc'
     [rapc] '@sources.txt'
     [rapc]
     [rapc] The ' characters around the executable and arguments are
     [rapc] not part of the command.
     [rapc] Setting environment variable: PATH=........etc
     [rapc] Reading resource: MyApp.cod
...etc
     [rapc] Parsing classfile: com/MyApp/ui/views/WelcomeBar.class
...etc
     [rapc] Parsing import: C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar(net_rim_amms.cod)
...etc
     [rapc] Resolving
...etc
     [rapc] Optimizing
     [rapc] Utilities.java:449: Warning!: local variable(s) { finished } initialized but not used in: com.cobi.library.Utilities.split(String,String)
...etc
     [rapc] Populating
     [rapc] Invoking: jar -cfmv C:\development\ant\new_test\MyApp\build\MyApp.jar C:\Users\Richard\AppData\Local\Temp\rapc_598c0c5a.dir\META-INF\MANIFEST.MF MyApp.cod MyApp-1.cod MyApp-2.cod MyApp.csl MyApp.cso -C C:\Users\Richard\AppData\Local\Temp\rapc_598c2ad7.dir .
     [rapc] added manifest
     [rapc] adding: MyApp.cod(in = 63208) (out= 41042)(deflated 35%)
     [rapc] adding: MyApp-1.cod(in = 75448) (out= 42559)(deflated 43%)
     [rapc] adding: MyApp.csl(in = 91) (out= 69)(deflated 24%)
     [rapc] adding: MyApp.cso(in = 157) (out= 93)(deflated 40%)
...etc - adding all files I can see in the JAR...

     [rapc] adding: MyApp-1.cod

     java.util.zip.ZipException: duplicate entry: MyApp-1.cod
     [rapc]     at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:175)
     [rapc]     at java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:92)
     [rapc]     at sun.tools.jar.Main.addFile(Main.java:713)
     [rapc]     at sun.tools.jar.Main.create(Main.java:466)
     [rapc]     at sun.tools.jar.Main.run(Main.java:180)
     [rapc]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     [rapc]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     [rapc]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     [rapc]     at java.lang.reflect.Method.invoke(Method.java:597)
     [rapc]     at net.rim.tools.compiler.c.e.if(Unknown Source)
     [rapc]     at net.rim.tools.compiler.c.e.a(Unknown Source)
     [rapc]     at net.rim.tools.compiler.Compiler.a(Unknown Source)
     [rapc]     at net.rim.tools.compiler.Compiler.a(Unknown Source)
     [rapc]     at net.rim.tools.compiler.Compiler.compile(Unknown Source)
     [rapc]     at net.rim.tools.compiler.Compiler.main(Unknown Source)

     [rapc] java.io.IOException: jar command failed: jar -cfmv C:\development\ant\new_test\MyApp\build\MyApp.jar C:\Users\Richard\AppData\Local\Temp\rapc_598c0c5a.dir\META-INF\MANIFEST.MF MyApp.cod MyApp-1.cod MyApp-2.cod MyApp.csl MyApp.cso -C C:\Users\Richard\AppData\Local\Temp\rapc_598c2ad7.dir .
     [rapc]     at net.rim.tools.compiler.Compiler.a(Unknown Source)
     [rapc]     at net.rim.tools.compiler.Compiler.a(Unknown Source)
     [rapc]     at net.rim.tools.I/O Error: jar command failed: jar -cfmv C:\development\ant\new_test\MyApp\build\MyApp.jar C:\Users\Richard\AppData\Local\Temp\rapc_598c0c5a.dir\META-INF\MANIFEST.MF MyApp.cod MyApp-1.cod MyApp-2.cocompiler.Compiler.compile(Unknown Source)
     [rapc]     at net.rim.tools.compiler.Compiler.main(Unknown Source)
     [rapc] d MyApp.csl MyApp.cso -C C:\Users\Richard\AppData\Local\Temp\rapc_598c2ad7.dir .

BUILD FAILED
C:\development\ant\new_test\MyApp\build.xml:65: Java returned: -1
        at org.apache.tools.ant.taskdefs.Java.execute(Java.java:111)
        at ca.slashdev.bb.tasks.RapcTask.executeRapc(RapcTask.java:583)
        at ca.slashdev.bb.tasks.RapcTask.execute(RapcTask.java:401)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:390)
        at org.apache.tools.ant.Target.performTasks(Target.java:411)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
        at org.apache.tools.ant.Main.runBuild(Main.java:809)
        at org.apache.tools.ant.Main.startAnt(Main.java:217)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Total time: 9 seconds

C:\development\ant\new_test\MyApp>
Workaround

Esaj имеетхороший ответ ниже который управляет муравьемreplace задание на исходный код перед выполнением компиляции. Это означает, что нет необходимости запускатьjarjar на любой результирующий файл JAR для решения проблем с пространством имен.

Это будет работать для меня, так как у меня есть исходный код SDK. Это не будет работать для моих клиентов, потому что я распространяю свой SDK в формате JAR. Поэтому я все еще надеюсь на ответ на этот вопрос в его нынешнем виде.

Related

этоis a duplicate из [Как конвертировать JAR FILE в файл COD с помощью Ant Build ], но на этот вопрос нет ответа, и я добавил более подробно.

Этоnot дубликат:

[ Convert a .jar file into a .cod file using bb-ant ] - I have used the accepted answer, and my error is different. [ BlackBerry - Ant script to include JAR in project without external dependancies ] - this question is about adding the library in as a JAR instead of using the source code as I do above. In a way, it is a precursor step, as its output would still need to be run through jarjar.
 Mister Smith17 мая 2012 г., 15:23
Если это так, попробуйте использоватьsrc а такжеfileset вместо.
 Richard Le Mesurier21 мая 2012 г., 08:02
Я используюsrc а такжеfileset уже, как предложено.
 Mister Smith17 мая 2012 г., 15:22
Ты используешьsrcdir указать папку, содержащую jar?

Ответы на вопрос(3)

Решение Вопроса

Чтобы ответить на мой собственный вопрос с некоторыми деталями ...

Нельзя звонитьrapc несколько раз - это создаст слишком много файлов ХПК. Вот почему я получил эту ошибку.

Вслед заМайкл ответправильный путь состоит в том, чтобы создать окончательный файл JAR с использованием обычных инструментов java (javac & amp; jar), а также RIM.preverify команда.

Использовать толькоrapc для последнего шага - преобразование этого файла JAR в ХПК.

Полная структура сборки ANT для решения этой проблемы слишком велика для размещения здесь, но шаги, необходимые для ее создания, перечислены ниже. Каждый из шагов может быть легко исследован на этом сайте (или с некоторым Google). Каждый шаг очень прост и может быть отлажен индивидуально.

Steps:

javac the SDK to create CLASS files preverify the CLASS files jar the SDK Copy the SDK JAR file into the project javac the project - use the SDK JAR as the classpath preverify the project CLASS files (again, use the SDK JAR in the classpath) jar the project - add the SDK JAR as a zipfileset jarjar this project JAR to refactor package names as required Finally, run rapc on this JAR - it will find no duplicate COD files & should run fine.

Note: Шаги 1-3 можно объединить, просто используяrapc в SDK (который необходим, если вам нужно запустить теги препроцессора для кода SDK).

Разобрав его на простые шаги, подобные этому, я узнал, как обычные инструменты Java связываются с цепочкой инструментов RIM (обычно это все скрыто, когда вы просто вызываетеrapc в исходной папке).

Конечно, вам все еще нужно подписать ХПК сsigtool.

Я делаю все это в АНТ. Я использую разные папки для хранения результатов каждого шага по ходу. Таким образом, я получаю 5 временных папок в конце, но это облегчает отладку шагов по ходу работы.

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

Полная инфраструктура сборки ANT для достижения этой цели может занимать много разных файлов (в моем случае я думаю, что сейчас я использую 8, включая файлы свойств). И для этого требуются хорошие знания ANT, обычные инструменты сборки Java и RIM.rapc команда.

Я думаю, что я достаточно хорошо задокументировал каждый шаг процесса в своих вопросах по этому поводу и нашел несколько отличных ответов по линии. Для более подробной информации, посмотрите на эти другие вопросы & amp; ответы. Каждая из них содержит полезные ссылки и некоторые полезные идеи от других разработчиков в этом сообществе.

Из вывода вашей консоли, команда, которая терпит неудачу:

jar -cfmv C:\development\ant\new_test\MyApp\build\MyApp.jar C:\Users\Richard\AppData\Local\Temp\rapc_598c0c5a.dir\META-INF\MANIFEST.MF MyApp.cod MyApp-1.cod MyApp-2.cod MyApp.csl MyApp.cso -C C:\Users\Richard\AppData\Local\Temp\rapc_598c2ad7.dir .

Поиск этих вариантов вдокументация по банке:

-C dir
Temporarily changes directories (cd dir) during execution of the jar command while processing the following inputfiles argument. Its operation is intended to be similar to the -C option of the UNIX tar utility.

Исходя из этого, я думаю, что rapc помещает распакованный файл cod в C: \ Users \ Richard \ AppData \ Local \ Temp \ rapc_598c2ad7.dir, и это вызывает конфликты с файлами cod, указанными в командной строке. Этот каталог все еще существует? Загляните внутрь, чтобы увидеть, что там.

 Richard Le Mesurier29 мая 2012 г., 11:36
@ Майкл, спасибо за подсказку - я разбил сборку на отдельные шаги и заставил ее работать. Подробно в моем ответе.
 21 мая 2012 г., 09:15
@RichardLeMesurier это звучит как хорошая идея.
 Richard Le Mesurier21 мая 2012 г., 08:01
1) каталог содержит все изображения & amp; текстовые ресурсы для приложения, а также файлы COD, как вы и ожидали, - вот почему это происходит. 2) эта команда вызывается автоматически bb-ant-tools & apos; Команда Rapc - возможно, мой INPUT JAR не должен включать файлы COD. Не могли бы вы создать этот JAR-файл с помощью обычной команды jar, а затем запустить Rapc только в качестве последнего шага?

Копирование этого ответа сBlackBerry - Ant скрипт для включения JAR в проект без внешних зависимостей согласно запросу @ RichardLeMesurier:

У меня была похожая проблема в прошлом году, я создал & quot; framework & quot; это использовалось в качестве основы для нескольких BB-приложений, но сталкивалось с проблемами с несколькими COD (я не помню точно, что, например, устройство отказывалось устанавливать несколько приложений, которые имели одинаковые внешние коды, если внешние COD не были сначала устанавливается отдельно, а затем и приложения). Поскольку приложения могут быть установлены отдельно (один человек может установить только приложение A, другой может установить только приложение B, а еще один может установить как A, так и B), необходимо интегрировать весь фреймворк во все приложения, использующие его. Я подготовил этот Ant-скрипт, используя bb-ant-tools (надеюсь, я ничего не сломал, удалив некоторые вещи, специфичные для наших приложений, запутав имена пакетов и т. Д.):

<?xml version="1.0" encoding="UTF-8"?>

<project name="${description}" default="build" basedir=".">

    <taskdef resource="bb-ant-defs.xml" classpath="lib/bb-ant-tools.jar" />

    <!-- rapc and sigtool require the jde.home property to be set -->
    <!-- NOTE: You may need to copy the signature files from Eclipse\plugins\net.rim.ejde\vmTools to the components\bin -dir 
        if the keys were installed using the Eclipse-plugin     -->
    <property name="jdehome" value="C:\BB\Eclipse\plugins\net.rim.ejde.componentpack5.0.0_5.0.0.25\components" />

    <!-- Framework source locations, these must be set correctly -->
    <property name="frameworkRes.dir" value="C:\BB\workspace\BB_Framework\res" />
    <property name="frameworkSrc.dir" value="C:\BB\workspace\BB_Framework\src\com\whatever\frame" />

    <!-- Locations for simulator, binaries, jde home, don't touch these -->
    <property name="simulator" value="${jdehome}\simulator" />
    <property name="bin" value="${jdehome}\bin" />
    <property name="jde.home" location="${jdehome}" />

    <!-- directory of simulator to copy files to -->
    <property name="simulator.home" location="${simulator}" />

    <property name="src.dir" location="src" />
    <property name="build.dir" location="build" />
    <property name="temp.dir" location="C:\tempsrc" />

    <!-- Project specific -->
    <!-- Application title -->
    <property name="app.title" value="Application Name" />
    <property name="app.version" value="1.0.0" />
    <!-- Value to prepend before frame-class packages -->
    <property name="frame.prefix" value="appname" />
    <!-- Name of the COD to produce --> 
    <property name="cod.name" value="Appname" />

    <target name="build">
        <mkdir dir="${build.dir}" />
        <delete dir="${temp.dir}" />
        <mkdir dir="${temp.dir}" />
        <mkdir dir="${temp.dir}\${frame.prefix}" />

        <copy toDir="${temp.dir}">
            <fileset dir="${src.dir}">
                <include name="**/*.java" />
            </fileset>
        </copy>

        <copy toDir="${temp.dir}\${frame.prefix}">
            <fileset dir="${frameworkSrc.dir}">
                <include name="**/*.java" />
            </fileset>
        </copy>

        <copy toDir="${temp.dir}\res">
            <fileset dir="${frameworkRes.dir}">
                <include name="**/*" />
            </fileset>
        </copy>

        <copy toDir="${temp.dir}\res">
            <fileset dir="res">
                <include name="**/*" />
            </fileset>
        </copy>

        <!-- This replaces the package names for classes copied from under 
            framework-directory to ${frame.prefix} -directory as well as changing any 
            imports using the classes in framework-package -->  
        <replace dir="${temp.dir}" value="${frame.prefix}">
            <include name="**/*.java"/>
            <replacetoken>com.whatever.frame</replacetoken>
        </replace>

        <rapc output="${cod.name}" srcdir="${temp.dir}" destdir="${build.dir}">
            <jdp title="${app.title}" 
                version="${app.version}" 
                vendor="Your Company"
                icon="../res/img/icon.png"
            />
        </rapc>
    </target>

    <target name="sign">
        <sigtool codfile="${build.dir}/${cod.name}.cod" />
    </target>

    <target name="clean">
        <delete dir="${build.dir}" />
    </target>

    <target name="load-simulator" depends="build">
        <copy todir="${simulator.home}">
            <fileset dir="${build.dir}" includes="*.cod,*.cso,*.debug,*.jad,*.jar" />
        </copy>
    </target>

</project>

Это копирует все java-файлы и ресурсы из вашего текущего проекта, а затем из framework-project во временный каталог, заменяя имена пакетов на пути к фреймворкам (так как они помещаются в отдельный файл). именованный каталог), это связано с тем, что устройства также отказались устанавливать несколько приложений, которые имели одинаковые классы в одних и тех же пакетах (а именно, классы платформы, в вашем случае это может не потребоваться). После того, как копирование и замена завершены, приложение собирается в целевой каталог сборки с помощью Rapc. Есть отдельные задачи для подписи, очистки и загрузки приложения в симулятор. Надеюсь это поможет.

 Richard Le Mesurier21 мая 2012 г., 09:19
Это очень полезный ответ, поскольку он обеспечивает очень хороший обходной путь - запустивreplaceнет необходимости бежатьjarjar, Предостережение - это работает, только если у вас есть доступ к исходному коду библиотеки (как у меня).

Ваш ответ на вопрос