Return-Path: X-Original-To: apmail-openjpa-dev-archive@www.apache.org Delivered-To: apmail-openjpa-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3369C77DA for ; Sat, 5 Nov 2011 16:17:16 +0000 (UTC) Received: (qmail 13378 invoked by uid 500); 5 Nov 2011 16:17:16 -0000 Delivered-To: apmail-openjpa-dev-archive@openjpa.apache.org Received: (qmail 13339 invoked by uid 500); 5 Nov 2011 16:17:16 -0000 Mailing-List: contact dev-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openjpa.apache.org Delivered-To: mailing list dev@openjpa.apache.org Received: (qmail 13331 invoked by uid 99); 5 Nov 2011 16:17:16 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 05 Nov 2011 16:17:16 +0000 X-ASF-Spam-Status: No, hits=-2001.2 required=5.0 tests=ALL_TRUSTED,RP_MATCHES_RCVD X-Spam-Check-By: apache.org Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 05 Nov 2011 16:17:12 +0000 Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116]) by hel.zones.apache.org (Postfix) with ESMTP id B199F3635D for ; Sat, 5 Nov 2011 16:16:51 +0000 (UTC) Date: Sat, 5 Nov 2011 16:16:51 +0000 (UTC) From: "Rick Curtis (Commented) (JIRA)" To: dev@openjpa.apache.org Message-ID: <2037724002.3136.1320509811728.JavaMail.tomcat@hel.zones.apache.org> In-Reply-To: <98824586.1275.1318349472025.JavaMail.tomcat@hel.zones.apache.org> Subject: [jira] [Commented] (OPENJPA-2057) Rethinking ClassLoading architecture MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/OPENJPA-2057?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13144738#comment-13144738 ] Rick Curtis commented on OPENJPA-2057: -------------------------------------- This change broke a number of our internal tests.... I spoke with Pinaki, and we agreed that I would back this change out while we investigate the failures. Thanks, Rick > Rethinking ClassLoading architecture > ------------------------------------- > > Key: OPENJPA-2057 > URL: https://issues.apache.org/jira/browse/OPENJPA-2057 > Project: OpenJPA > Issue Type: Improvement > Components: kernel > Reporter: Pinaki Poddar > Assignee: Rick Curtis > > This issue proposes an overhaul of the classloading architecture. > Background: > ------------------ > OpenJPA runtime needs to load classes and resources at various time points in its life cycle and employs various classloading strategies at different parts of its code base. > These are few broad categories of classes/resources OpenJPA needs to load > 1. Resources: user-specified resources such as persistence.xml or orm.xml > 2. Persistent Domain classes > 3. Native Plug-ins: Implementation of interfaces e.g. UpdateManager that are supplied by OpenJPA and packaged in its own distribution > 4. User Plug-ins: Implementation of interfaces e.g. MappingStrategy or ValueHandlers that the user has supplied via configuration and packaged in deployed units > 5. Temporary classloader for java agent or weaving code loading domain classes to enhance them prior to their use > To load these different artifacts by their name, OpenJPA at different places employ available classloaders such as > i) the current thread's context class loader > ii) the clasloader that loaded OpenJPA native classes/interfaces > iii) the classloader that loaded a deployed application which can vary based on the container (Spring, OSGi, JEE) environment > iv) system classloader > The problem is the decision about which classloader is appropriate in a given context is quite scattered. This weakness appears in numerous places where a method is supplied with a ClassLoader and if the supplied loader is null, the method chooses a classloader (often the context classloader) or a class has its own classforname() method that tries a series of classloaders etc. > This is a perennial problem and manifested in several reported bugs whose resolutions often introduced further localized logic to account for the point defects, thereby accentuating the same trends that I believe is the root cause of the problem itself. > Proposed solution/design: > ------------------------------------- > Unify classloading decision in a singular abstraction. > Allow that abstraction to cope with classloading regimes of different containers (Spring, OSGi, JEE etc). > The natural candidate for unifying classloading is existing Configuration object. This object is a per persistence unit singleton and available throughout the runtime. > However, certain class/resource loading must take place even before a Configuration instance is instantiated. For example, to locate and load the persistence.xml itself. > Also note that the persistence.xml or orm.xml may contain fully-qualified names of persistent domain classes or plug-in names (both native and custom/user variety) and they can occur either by their fully-qualified class name or registered alias. The specialized parsers often has to load the class given their parsed string names or aliases. > The bootstrap sequence of OpenJPA runtime is to construct a specific ConfigurationProvider and a series of specialized parsers to parse meta-data of various sorts (annotations, mapping xml, persistence.xml). These ConfigurationProviders are responsibilities of ProductDerivation -- the core mechanics that contributes their individual aspects to build up a Configuration. > Given this existing well-designed bootstrap strategy, here is a proposal > 1. Let each ProductDerivation make their decision on how they will load whatever they need to load using whatever classloader they may need. For example, a OSGi ProductDerivation will use a bundle classloader to load its relevant resources. This phase occurs *before* a persistence unit (i.e. EntityManagerFactory) is constructed. > 2. Once the ProductDerivations have finished their loading using their own ConfigurationProvider, they transfer the accumulated information to a Configuration instance which essentially becomes the holder of entire runtime information for an EntityManagerFactory. During this transfer phase, let the ProductDerivations set the classloader as well into the Configuration instance. > 3. Once the Configuration instance has the classloader, this classloader is used throughout the codebase. > But what kind of classloader is used by the Configuration that will suit complex needs of class/resource loading? > OpenJPA already has a powerful abstraction called MultiClassLoader which can employ an ordered series of (possibly unrelated) classloaders. So that MultiClassLoader is the correct classloader for Configuration instance. The ProductDerivation or ConfigurationProvider can add/remove their contributions. > I understand that a change of this nature could be destabilizing in short-term. Also the change is difficult to validate across various container environments. I hope the community users will help by suggesting and testing such an overhaul to streamline OpenJPA classloading for long-term sustainability and maintenance. > > -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa For more information on JIRA, see: http://www.atlassian.com/software/jira