geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Shiva Kumar H R" <shiv...@gmail.com>
Subject Re: Stuck in discovering Annotations - Please Help!
Date Thu, 05 Jul 2007 16:04:14 GMT
On 7/2/07, Shiva Kumar H R <shivahr@gmail.com> wrote:
>
> Following the working of NamingBuilders, I have arrived at the following
> piece of code:
>
> 1) Code called from Portlet:
>     private static void parseAnnotations(AnnotatedApp annotatedApp,
> ClassFinder classFinder) throws Exception {
>         ResourceAnnotationHelper.processAnnotations(annotatedApp,
> classFinder, EnvEntryRefProcessor.INSTANCE);
>         WebServiceRefAnnotationHelper.processAnnotations(annotatedApp,
> classFinder);
>         HandlerChainAnnotationHelper.processAnnotations (annotatedApp,
> classFinder);
>         ResourceAnnotationHelper.processAnnotations(annotatedApp,
> classFinder, ServiceRefProcessor.INSTANCE);
>         ResourceAnnotationHelper.processAnnotations(annotatedApp,
> classFinder, AdminObjectRefProcessor.INSTANCE);
>         ResourceAnnotationHelper.processAnnotations(annotatedApp,
> classFinder, ResourceRefProcessor.INSTANCE);
>         PersistenceContextAnnotationHelper.processAnnotations(annotatedApp,
> classFinder);
>         PersistenceUnitAnnotationHelper.processAnnotations(annotatedApp,
> classFinder);
>         EJBAnnotationHelper.processAnnotations(annotatedApp, classFinder);
>         if (annotatedApp instanceof AnnotatedWebApp) {
>             SecurityAnnotationHelper.processAnnotations(((AnnotatedWebApp)
> annotatedApp).getWebApp(), classFinder);
>         }
>     }
>
>     private static Module createModule(PortletRequest request, URL
> moduleUrl) throws Exception {
>         Object[] builders = PortletManager.getGBeansImplementing(request,
> ConfigurationBuilder.class);
>         ConfigurationBuilder configurationBuilder = null;
>         for (int i = 0; i < builders.length; i++) {
>             ObjectName objectName = PortletManager.getNameFor(request,
> builders[i]).getObjectName();
>             if ("EARBuilder".equalsIgnoreCase(objectName.getKeyProperty(
> NameFactory.J2EE_NAME))) {
>                 configurationBuilder = (ConfigurationBuilder) builders[i];
>
>                 break;
>             }
>         }
>         JarFile moduleJar = DeploymentUtil.createJarFile(new File(
> moduleUrl.toURI()));
>         ApplicationInfo applicationInfo = (ApplicationInfo)
> configurationBuilder.getDeploymentPlan (null, moduleJar, new
> ModuleIDBuilder());
>         Module module = (Module) (applicationInfo.getModules
> ().toArray()[0]);
>         return module;
>     }
>
>     // function called from Portlet Handler
>     public static void parseWarReferences(PortletRequest request,
> WARConfigData data, URL warUrl)
>             throws Exception {
>         WebDeployable webDeployable = new WebDeployable(warUrl);
>
>         Module module = createModule(request, warUrl);
>         WebAppType webApp = (WebAppType) module.getSpecDD();
>         ClassLoader classLoader = webDeployable.getModuleLoader();
>         ClassFinder classFinder = null;
>         try {
>             classFinder = AbstractWebModuleBuilder.createWebAppClassFinder(webApp,
> classLoader);
>             // classFinder = new ClassFinder(webDeployable.getModuleLoader
> ());
>         } catch (NoClassDefFoundError e1) {
>             // Some of the class types referred in the WAR cannot be
> resolved.
>             // A typical case would be references to EJBs already deployed
> into the system, and
>             // hence not packaged inside WEB-INF/lib directory of WAR.
>             // try adding all EJBs deployed in the system as parents of
> this WAR, and
>             // see if referred classes can now be succesfully resolved
>
>             //TODO create a new class loader with deployed-ejbs as parents
>             MultiParentClassLoader newClassLoader = null; //TODO
>             try {
>                 classFinder =
> AbstractWebModuleBuilder.createWebAppClassFinder(webApp, classLoader);
>             } catch (NoClassDefFoundError e2) {
>                 return;
>             }
>         }
>         AnnotatedApp annotatedApp = module.getAnnotatedApp();
>         parseAnnotations(annotatedApp, classFinder);
>
>         EjbRefType[] ejbRefs = annotatedApp.getEjbRefArray();
>         for (int i = 0; i < ejbRefs.length; i++) {
>             String refName = ejbRefs[i].getEjbRefName().getStringValue();
>             data.getEjbRefs().add(new ReferenceData(refName));
>         }
>
>         EjbLocalRefType[] ejbLocalRefs = annotatedApp.getEjbLocalRefArray
> ();
>         for (int i = 0; i < ejbLocalRefs.length; i++) {
>             String refName =
> ejbLocalRefs[i].getEjbRefName().getStringValue();
>             data.getEjbLocalRefs().add(new ReferenceData(refName));
>         }
>
>         ResourceRefType[] resourceRefs = annotatedApp.getResourceRefArray
> ();
>         for(int i = 0; i < resourceRefs.length; i++) {
>             String refName =
> resourceRefs[i].getResRefName().getStringValue();
>             String refType =
> resourceRefs[i].getResType().getStringValue();
>             if ("javax.sql.DataSource".equalsIgnoreCase(refType)) {
>                 data.getJdbcPoolRefs().add(new ReferenceData(refName));
>             } else if ("javax.jms.ConnectionFactory
> ".equalsIgnoreCase(refType)
>                     || "javax.jms.QueueConnectionFactory
> ".equalsIgnoreCase(refType)
>                     || " javax.jms.TopicConnectionFactory".equalsIgnoreCase(refType))
> {
>                 data.getJmsConnectionFactoryRefs().add(new
> ReferenceData(refName));
>             }
>         }
>
>         ResourceEnvRefType[] resourceEnvRefs =
> annotatedApp.getResourceEnvRefArray();
>         for(int i = 0; i < resourceEnvRefs.length; i++) {
>             String refName =
> resourceEnvRefs[i].getResourceEnvRefName().getStringValue();
>             ReferenceData refData = new ReferenceData(refName);
>             refData.setRefLink(refName);
>             data.getJmsDestinationRefs().add(refData);
>         }
>         if(annotatedApp instanceof AnnotatedWebApp) {
>             MessageDestinationType[] messageDestinations =
> ((AnnotatedWebApp)annotatedApp).getWebApp().getMessageDestinationArray();
>             for(int i = 0; i < messageDestinations.length; i++) {
>                 String refName =
> messageDestinations[i].getMessageDestinationName().getStringValue();
>                 ReferenceData refData = new ReferenceData(refName);
>                 refData.setRefLink(refName);
>                 data.getMessageDestinations().add(refData);
>             }
>         }
>     }
>
> 2) Changes required to AdminObjectRefBuilder and AbstractWebModuleBuilder:
>
> <please see attached file AdminObjectRefBuilder.patch>
>
> With my limited set of test WARs, I observe that although this code works
> for @Resource annotations (references to JMS Connection Factories, JMS
> Destinations and JDBC Connection Pools), it fails for @EJB annotations as
> explained below.
>
> Please suggest if above code would be acceptable. Suggestions/Hints of
> doing it better is welcome. I suspect there might be better ways of creating
> 'Module' object (with a proper EARContext, yet not deploying it in the
> system) and 'ClassFinder' objects.
>
> Here is one failure scenario for EJB references:
> Input WAR has a Servelt that references an EJB as below:
>     @EJB(name = "ejb/Converter")
>     private Converter converter;
> The referenced EJB ('Converter') is already deployed in the system.
>
> When function "parseWarReferences()" above is called for this WAR, it
> would fail at
> "classFinder = AbstractWebModuleBuilder.createWebAppClassFinder (webApp,
> classLoader);"
> with a ClassNotFoundError for "Converter" EJB.
>
> Following is the solution I can think of:
> Try adding all EJBs deployed in the system as dependencies of this WAR
> (temporarily), and see if referred classes can now be succesfully resolved
> while creating ClassFinder object.
>
> The question then would be "given the pattern name for an EJB JAR (like
> 'default/CurrencyConverterEJB/1.0/jar' how do I obtain a reference to this
> deployed EJB-JAR's classloader? " Any hints will be helpful.


Found a way for doing this :)

    private static List getConfigClassLoaders(List configurationNames) {
        List classLoaders = new ArrayList();
        ConfigurationManager configurationManager =
PortletManager.getConfigurationManager();
        for (int i = 0; i < configurationNames.size(); i++) {
            Artifact configurationId = Artifact.create((String)
configurationNames.get(i));
            classLoaders.add(configurationManager.getConfiguration
(configurationId).getConfigurationClassLoader());
        }
        return classLoaders;
    }

Will now work on handling Web Service References and Security Settings in a
WAR.

Thanks,
> Shiva
>
> On 6/27/07, Shiva Kumar H R <shivahr@gmail.com > wrote:
> >
> > Thanks David. Will look into the working of NamingBuilders.
> >
> > - Shiva
> >
> > On 6/26/07, David Jencks < david_jencks@yahoo.com > wrote:
> > >
> > >
> > > On Jun 26, 2007, at 8:13 AM, Shiva Kumar H R wrote:
> > >
> > > This is with regard to auto generation of Geronimo deployment plans (http://issues.apache.org/jira/browse/GERONIMO-3254).
> > > One problem where I am currently stuck is in the discovery of Annotations.
> > >
> > > User input to my wizard/portlet would be the Java EE module
> > > (WAR/EJB-JAR/EAR) and output would be the Geronimo deployment plan. An
> > > important step in this process is to discover all references declared in the
> > > Java EE module and then ask the user to resolve them ( http://issues.apache.org/jira/secure/attachment/12360303/3ResolveReferences.gif
> > > ).
> > >
> > > References declared in the spec deployment descriptor (
> > > web.xml/ejb-jar.xml) can easily be discovered by parsing the spec DD
> > > (lines 921 to 959 of
> > > http://issues.apache.org/jira/secure/attachment/12360289/PoC.patch).
> > > References declared as Annotations in java code (with probably no mention in
> > > the spec DD) is what is posing the problem now.
> > >
> > > Are there any standard APIs that simplify the job of discovering these
> > > Annotations (and optionally get them into the spec DD)? Please note that
> > > this must be achieved without the need for actually deploying the Java EE
> > > module onto the server (user is in the process of still creating the
> > > Geronimo deployment plan using wizard/portlet).
> > >
> > > Any help and hints is greatly appreciated.
> > >
> > >
> > > roughly the first thing the NamingBuilders do is find all the relevant
> > > annotations and modify the spec dd by adding xml with the same meaning (when
> > > not already overridden).  I recommend you figure out how this works and use
> > > the NamingBuilders to do this.  You might need to expose another method on
> > > the naming builders for your portlet to call.
> > >
> > > thanks
> > > david jencks
> > >
> > >
> > > Thanks,
> > > Shiva
> > >
> > >
> > >
> >
>
>

Mime
View raw message