“java.lang.IllegalArgumentException异常:已添加” 建设项目,该项目依赖于库项目
鉴于“java.lang.IllegalArgumentException异常:已添加” 建设项目,该项目依赖于库项目
Commons - simple java project
AndroidLibrary1 - android library
AndroidLibrary2 - android library
AndroidProject - android project
何时该项目有这样的引用对方:
AndroidLibrary1 -> Commons
AndroidLibrary2 -> Commons
AndroidProject -> AndroidLibrary1, AndroidLibrary2
问题
当我建立AndroidProject我得到这样的错误:
java.lang.IllegalArgumentException: already added: Lcom/test/Bar;
其中“com.test.Bar”是一类由“共享”工程,即通过双方AndroidLibrary1和AndroidLibrary2使用。
环境
Eclipse 3.7.1
android-sdk-windows_r15
任何想法如何解决这一问题?
编辑: 找到相关discussion。
后相当长的时间和正则表达式的黑魔法我发现这个解决方案:
<target name="-post-compile">
<macrodef name="dex-helper">
<element name="external-libs" optional="yes" />
<attribute name="nolocals" default="false" />
<sequential>
<!-- sets the primary input for dex. If a pre-dex task sets it to
something else this has no effect -->
<property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" />
<!-- set the secondary dx input: the project (and library) jar files
If a pre-dex task sets it to something else this has no effect -->
<if>
<condition>
<isreference refid="out.dex.jar.input.ref" />
</condition>
<else>
<path id="out.dex.jar.input.ref">
<path refid="jar.libs.ref" />
</path>
</else>
</if>
<if>
<condition>
<length string="${toString:out.dex.jar.input.ref}" trim="true" when="greater" length="0"/>
</condition>
<then>
<echo message="${toString:out.dex.jar.input.ref}" file="antler.tmp" />
<loadfile property="out.dex.jar.input.ref.fixed" srcFile="antler.tmp">
<filterchain>
<tokenfilter>
<replaceregex
pattern="(?<=;|^)[^;]+\\libs\\([^\\;]+)(?:;|$)(?=(?:(?<=;|^)[^;]+(?:;|$))*(?<=;|^)[^;]+\\\1(?:;|$))"
replace="" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<delete file="antler.tmp"/>
<path id="out.dex.jar.input.ref.fixed" path="${out.dex.jar.input.ref.fixed}"/>
</then>
<else>
<path id="out.dex.jar.input.ref.fixed" />
</else>
</if>
<dex executable="${dx}"
output="${intermediate.dex.file}"
nolocals="@{nolocals}"
verbose="${verbose}">
<path path="${out.dex.input.absolute.dir}"/>
<path refid="out.dex.jar.input.ref.fixed" />
<external-libs />
</dex>
</sequential>
</macrodef>
</target>
这是你应该<import file="${sdk.dir}/tools/ant/build.xml" />
行前添加什么到你的build.xml 文件。如果您在几个项目的libs文件夹中有相同的JAR,则此代码将根据文件名从构建系统中删除重复条目。
现在,这是如何工作
我会用“图书馆”在库文件夹,JAR和“库项目”对这些其他项目可能取决于Android的库项目。问题是,当Android系统使用库项目构建项目时,它会将所有库合并为一个堆,而忽略可能存在重复的事实。所以我们必须修复路径。
所以当构建到达那里编译完成的时候,我们重新定义它负责将Java代码到DEX的部分。上面的代码是完全一样在Android构建工具,除了以下部分:
<if>
<condition>
<length string="${toString:out.dex.jar.input.ref}" trim="true" when="greater" length="0"/>
</condition>
<then>
<echo message="${toString:out.dex.jar.input.ref}" file="antler.tmp" />
<loadfile property="out.dex.jar.input.ref.fixed" srcFile="antler.tmp">
<filterchain>
<tokenfilter>
<replaceregex
pattern="(?<=;|^)[^;]+\\libs\\([^\\;]+)(?:;|$)(?=(?:(?<=;|^)[^;]+(?:;|$))*(?<=;|^)[^;]+\\\1(?:;|$))"
replace="" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<delete file="antler.tmp"/>
<path id="out.dex.jar.input.ref.fixed" path="${out.dex.jar.input.ref.fixed}"/>
</then>
<else>
<path id="out.dex.jar.input.ref.fixed" />
</else>
</if>
我们在out.dex.jar.input.ref
不洁的路径,我们的目标是不重复的条目创建路径(它们将被存储在out.dex.jar.input.ref.fixed
)。不幸的是,我们必须卸载文件的路径,将其更改并加载回去,因为ant出于某些奇怪的原因无法在属性中使用正则表达式(除非使用外部库,如ant-contrib)。
其中的伎俩正则表达式是(?<=;|^)[^;]+\\libs\\([^\\;]+)(?:;|$)(?=(?:(?<=;|^)[^;]+(?:;|$))*(?<=;|^)[^;]+\\\1(?:;|$))
。这种可怕的符号的混乱与libs\<something.jar>
结束,并且具有进一步某处与<something.jar>
结束另一路径的路径相匹配。 我正则表达式使用Windows分离,所以如果你是Linux或Mac OS X下,你应该改变那些\\
必要的分离器或使正则表达式普遍。对不起,我只是没有心情去修复它已经花费了太多时间。如果你想看看正则表达式的工作原理,你可以在Regexr上这样做。
当我们删除重复项后,我们只需将字符串加载回新路径out.dex.jar.input.ref.fixed
并使用它来运行dex。希望我的解决方案有帮
你如何定义你的依赖关系的引用。我用最新版本的ADT(r16)重新创建了你的设置,它编译得很好。 – Kingamajick 2012-02-01 03:05:56
我刚才有一个类似的问题。我的主要Android项目引用了两个android库项目(通过project.properties)。我的主要项目使用兼容性包,它放在libs中。其中一个库项目也使用它,该包也在库项目的libs文件夹中。我从主项目中删除了这个包,并且工作。 alex2k8在他的两个库项目中都有相同的库,这就是为什么它失败了。但在我看来,Android构建系统已经崩溃,所以无法编辑构建文件就无法解决这个问题。 – Malcolm 2012-02-01 12:02:56
@Kingamajick,我刚刚尝试r16,同样的问题。实际上,我的描述并不精确......当我做“构建”时,报告没有问题,但是当我尝试“运行”项目时,它会报告该问题。 – alex2k8 2012-02-01 17:46:35