我得到java.lang.AbstractMethodError
一个特定的案例(只有当我用蚂蚁创建一个我的类的jar)时我才能理解它。一些有助于理解这一点将非常感激。
考虑以下情况(出于某种原因,我要将代码层次保留在我的代码中,如下例所示,我认为这样做不应该给我一个AbstractMethodError!):
public interface Cat {
void speak();
}
public interface ColoredHeadCat extends Cat {
boolean isColoredHead();
}
public interface RedHeadCat extends ColoredHeadCat {
boolean isRedHead();
}
public interface SuperRedCat extends RedHeadCat {
boolean isSuperCat();
}
public abstract class AbstractCat {
public void speak() {
System.out.println("Meow!");
}
}
public abstract class AbstractColoredHeadCat extends AbstractCat {
// .. Not overriding speak() method here
public boolean isColoredHead() {
return true;
}
}
public abstract class AbstractRedHeadCat extends AbstractColoredHeadCat {
// .. Not overriding speak() method here
public boolean isRedHead() {
return true;
}
}
public class SuperRedHeadCat extends AbstractRedHeadCat implements SuperRedCat {
// .. Not overriding speak() method here too
public boolean isSuperCat() {
return true;
}
}
public class Main {
public static void main(String[] arrgh) {
SuperRedHeadCat superCat = new SuperRedHeadCat();
superCat.speak(); // No exceptions! Works like charm.
Cat cat = new SuperRedHeadCat();
cat.speak(); // Gives java.lang.AbstractMethodError! Why?
}
}
所有类都在同一个包中。
所以问题是我无法通过Eclipse重现这一点:一切都运行得很好。但是在使用ant
构建一个jar后,然后运行'Main'会抛出AbstractMethodError
。我在这里没有关于这种行为的原因。
java -version
java版“1.6.0_27”
Java(TM)SE运行时环境(版本1.6.0_27-b07)
Java HotSpot(TM)64位服务器VM(版本20.2-b06,混合模式)
ant -version
2010年2月1日编译的Apache Ant版本1.8.0
P.S。:除了Main
类之外,其余的类在蚂蚁构建期间被混淆
如果我允许AbstractCat
实现Cat
接口,AbstractColoredHeadCat
实现ColoredHeadCat
接口和AbstractRedHeadCat
实现RedHeadCat
接口,则此问题已得到解决。
答案 0 :(得分:0)
你在使用哪个混淆器?
我尝试使用yguard并且工作正常:
<taskdef name="obfuscate" classname="com.yworks.yguard.YGuardTask" classpath="c:/Soft/Java/yguard-2.5.3/lib/yguard.jar" />
<target name="obf" depends="jar">
<obfuscate >
<property name="error-checking" value="pedantic"/>
<inoutpair in="target/cat.jar" out="target/obf.jar"/>
<shrink >
<property name="error-checking" value="pedantic"/>
<keep>
<method name="void main(java.lang.String[])" class="Main"/>
</keep>
</shrink>
<rename mainclass="Main">
<expose >
<class classes="public" methods="public" fields="public">
<patternset>
<include name="**.*"/>
<exclude name="Main"/>
</patternset>
</class>
</expose>
</rename>
</obfuscate>
</target>