Bug 1113485
Summary: | Using POST in /api resources results in HTTP 500 | ||
---|---|---|---|
Product: | [Retired] oVirt | Reporter: | Idan Shaby <ishaby> |
Component: | ovirt-engine-api | Assignee: | Juan Hernández <juan.hernandez> |
Status: | CLOSED CURRENTRELEASE | QA Contact: | Petr Beňas <pbenas> |
Severity: | high | Docs Contact: | |
Priority: | urgent | ||
Version: | 3.5 | CC: | alukiano, amureini, gcheresh, gklein, iheim, ishaby, myakove, pstehlik, rbalakri, sbonazzo, yeylon |
Target Milestone: | --- | Keywords: | AutomationBlocker, Regression |
Target Release: | 3.5.0 | ||
Hardware: | Unspecified | ||
OS: | Unspecified | ||
Whiteboard: | infra | ||
Fixed In Version: | ovirt-3.5.0-beta1.1 | Doc Type: | Bug Fix |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2014-10-17 12:44:49 UTC | Type: | Bug |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | Infra | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | |||
Bug Blocks: | 1073943 |
Description
Idan Shaby
2014-06-26 09:29:54 UTC
The RESTAPI application is deployed twice, once for /api and another time for /ovirt-engine/api. This means that classes like o.o.e.a.m.StorageDomain are loaded twice. In theory this shouldn't result in a class cast exception, as the class loaders for WEB-INF/lib of both applications should be isolated, but this is always tricky. What version of the application server are you exactly using? Juan, looks like a blocker. If you agree, please add this to bug #1073943, thanks. I already added it as a blocker. This is what is happening: 1. The RESTAPI application is loaded twice, once from the legacy_restapi.war file in order to serve /api, and another time named restapi.war file in order to serve /ovirt-engine/api. 2. The dependencies of the RESTAPI are .jar files inside WEB-INF/lib, in particular the .jar file containing the StorageDomain class is restapi-definition.jar. This file is loaded once for each instance of the application, so there are two class loaders that can provide this class. In theory these class loaders are isolated. 3. The classes of Resteasy are loaded only once, as they are part of the application server. 4. When a resource is requested Resteasy lazily loads the required providers, using the Java SPI mechanism. These providers are stored in a global cache implemented as a singleton by Resteasy. 5. Our own providers (JsonProvider and JAXBProvider) are deployed twice, as a result of the double deployment of the RESTAPI application. 6. Depending on the order of requests Resteasy will load our own providers in different orders, so the content of the global cache of providers depends on the order of requests. For example, if a request to /ovirt-engine/api is made first the global cache will contain the provider from restapi.war. A later request to /api will not load the provider from legacy_restapi.war, as it is already loaded. 7. When the provider requests a class like StorageDomain it will get it from its own class loader. So the provider loaded from legacy_restapi.war will get the class from legacy_restapi.war, regardless of the order of requests. 8. Resteasy doesn't store resources in a global cache, but separated by application. So when Resteasy invokes the StorageDomainResource.add() method on a resource loaded from legacy_restapi.war it may be passing a StorageDomain instance that was created by a provider loaded from restapi.war. So the expected and passed classes are actually different, as they have been loaded by different class loaders. All in all, the class loader used to load classes like StorageDomain depends on the order of invocation. Actually, if you restart the application server, and close the webadmin page, things will work correctly, because the first request to /api will load the provider provider from legacy_restapi.war. If you start webadmin then it will send requests to /ovirt-engine/api, and load the provider from restapi.war, triggering this issue. The solution to this problem is to make sure that RESTAPI classes are loaded only once, which isn't trivial. This may affect 3.4 as well. *** Bug 1114955 has been marked as a duplicate of this bug. *** The 3.5 branch will be removed and re-created from master, so moving to MODIFIED. *** Bug 1116764 has been marked as a duplicate of this bug. *** Verified in ovirt-engine-3.5.0-0.0.master.20140804172041.git23b558e.el6.noarch. The operation is synchronous, but succeeded. oVirt 3.5 has been released and should include the fix for this issue. |