dev@glassfish.java.net

Re: LinkageError caused by java.lang.VerifyError ... Bad type in putfield/putstatic ?

From: Richard S. Hall <heavy_at_ungoverned.org>
Date: Wed, 27 May 2009 17:08:35 -0400

On 5/27/09 4:59 PM, Marina Vatkina wrote:
> Ken,
>
> Is it possible to remove duplicate classes from the
> glassfish-corba-xxx modules?

The duplicate classes are not really the issue. The issue is that the
built-in JRE package is incomplete, so we somehow need to add the
missing classes to the package. Unfortunately, we cannot just completely
override the JRE package by placing it in a bundle, since other JRE
classes use types from the incomplete package ("uses" constraints in
OSGi terms).

To work around this issue, we need to merge the existing classes in the
JRE package with the additional classes being exported by the exporting
bundle. The only way we can accomplish something like this in OSGi is to
do as Sahoo suggests and use boot delegation to find the existing JRE
classes, but have bundles still import the package so they can fall back
to the exporting bundle for the missing classes.

This will work, since no JRE packages will depend on the missing
classes. We just need to make sure the exporting bundle is version
compatible with the JRE package.

-> richard

>
> thanks,
> -marina
>
> Sahoo wrote:
>> I think I know what's happening here. I am a bit surprised that it
>> didn't result in a "loader constraint violation," which is also a
>> LinkageError, but any way, I think I have an explanation for this
>> linkage error.
>>
>> /javap -classpath orb-iiop.jar -p -c
>> org.glassfish.enterprise.iiop.impl.GlassFishORBManager
>> /shows the following bytecodes:
>> * 495: invokestatic #114; //Method
>> com/sun/corba/ee/spi/osgi/ORBFactory.create:([Ljava/lang/String;Ljava/util/Properties;Z)Lcom/sun/corba/e
>>
>> e/spi/orb/ORB;
>> 498: putfield #2; //Field orb:Lorg/omg/CORBA/ORB;
>> *
>> Basically, it translates to something like this:
>> org.omg.CORBA.ORB something =
>> com.sun.corba.ee.spi.osgi.ORBFactory.create(properties);
>>
>> com.sun.corba.ee.spi.osgi.ORBFactory.create(Properties) returns
>> com.sun.corba.ee.spi.orb.ORB, which definitely extends
>> org.omg.CORBA.ORB for the code to compile. So, let's inspect the
>> hierarchy of this class:
>>
>> (*->* means extends and within bracket the jar that supplies the
>> class is mentioned as well. Each jar has a separate class loader)
>>
>> com.sun.corba.ee.spi.orb.ORB (/glassfish-corba-orb.jar/)
>> -> com.sun.corba.ee.org.omg.CORBA.ORB (/glassfish-corba-omgapi.jar/)
>> -> org.omg.CORBA_2_3.ORB (/JDK's rt.jar/)
>> -> org.omg.CORBA.ORB (/JDK's rt.jar/)
>>
>> Note a *duplication* of class in the runtime:
>> glassfish-corba-omgapi.jar exports org.omg.CORBA package and has
>> org.omg.CORBA.ORB.class in it.
>> JDK's rt.jar also has org.omg.CORBA.ORB.class.
>>
>> Since you *removed* org.omg.CORBA from system.packages list,
>> GlassFishORBManager, which is loaded from org-iiop.jar module, gets
>> org.omg.CORBA.ORB.class from glassfish-corba-omgapi.jar. As a result,
>> the simple assignment is looking like this:
>>
>> *org.omg.CORBA.ORB(glassfish-corba-omgapi.jar) = org.omg.CORBA.ORB
>> (JDK's rt.jar)*
>>
>> As you can see, they are two different types and hence the
>> VerificationError.
>>
>> There are several ways to *solve* it.
>>
>> 1. If you add a *bootdelegation* property for org.omg.CORBA package,
>> then everyone will see org.omg.CORBA.ORB(JDK's rt.jar) and that will
>> address the issue. Although this solution looks simple, it is not
>> preferred, as it is a violation of modularity principle. More over,
>> it leads to split packages which can lead to other issues at runtime
>> like access violation of package scoped objects.
>>
>> 2. If you remove all the org.omg CORBA related packages (including
>> org.omg.CORBA_2_3) from system packages list and ensure that they are
>> exported by glassfish-corba-omgapi bundle, then also every one will
>> see one version of classes and the problem will be solved. There is
>> an assumption here that no other JDK class other than the CORBA
>> implementation has direct reference to these packages.
>>
>> 3. If we can put glassfish-corba-omgapi.jar in one of the
>> java.endorsed.dirs and add all the new packages to system.packages
>> list, then also everyone see one consistent version of classes. Since
>> we can't assume we are using jre/lib/endorsed, this has the
>> disadvantage of requiring user to specify -Djava.endorsed.dirs in
>> command line, something which does not fly with "java -jar
>> glassfish.jar" style invocation.
>>
>> For now, I think we can start with option #2 and if we face any
>> issues, we can go to #1.
>>
>> Now let's see why the error was so cryptic in an OSGi environment.
>> After all, OSGi is supposed to give us more helpful errors. The
>> problem is our system packages are exported without any "uses"
>> clause. "uses" clause plays a vital role in package resolution and
>> correct specification of uses attribute might have given us a better
>> error stating the class space was not consistent.
>>
>> Hope that helps,
>> Thanks,
>> Sahoo
>>
>> Marina Vatkina wrote:
>>
>>> Team,
>>>
>>> Does anybody know what can cause this type of a LinkageError:
>>>
>>> Caused by: java.lang.VerifyError: (class:
>>> org/glassfish/enterprise/iiop/impl/GlassFishORBManager, method:
>>> initORB signature: (Ljava/util/Properties;)V) Bad type in
>>> putfield/putstatic
>>> at
>>> org.glassfish.enterprise.iiop.impl.GlassFishORBFactoryImpl.postConstruct(GlassFishORBFactoryImpl.java:29)
>>>
>>> at
>>> com.sun.hk2.component.AbstractWombImpl.inject(AbstractWombImpl.java:170)
>>>
>>>
>>>
>>> I see this error if I remove org.omg.CORBA package (only it, not its
>>> subpackages) from the
>>> glassfishv3/glassfish/osgi/felix/conf/config.properties (because
>>> it's available in the glassfish-corba-omgapi module) and then try to
>>> deploy an app with remote EJBs (i.e. force orb integration modules
>>> to be loaded). The same error happens on server restart if I first
>>> deploy the app, then modify the felix/conf/config.properties file.
>>>
>>> Googling for this error brings cases when 2 versions of the same
>>> class was present in 2 jars. But GlassFishORBManager is there in
>>> only one. Or a jdk 1.4 bug where you downcast the result to one of
>>> the interfaces (String to Clonable), which a) had been fixed back
>>> then and b) doesn't seem to be the case here as well :(.
>>>
>>> It doesn't make a difference whether I start GF via 'java -jar' or
>>> asadmin.
>>>
>>> Any ideas are greatly appreciated.
>>>
>>> thank you,
>>> -marina
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>