You are viewing a plain text version of this content. The canonical link for it is here.
Posted to m2-dev@maven.apache.org by jd...@apache.org on 2005/02/08 21:51:48 UTC

cvs commit: maven-components/maven-core/src/site/apt/scripting-support marmalade-support.apt

jdcasey     2005/02/08 12:51:48

  Added:       maven-core/src/site/apt/scripting-support
                        marmalade-support.apt
  Log:
  o First iteration of discussion on implementing marmalade scripting support for mojos.
  
  Revision  Changes    Path
  1.1                  maven-components/maven-core/src/site/apt/scripting-support/marmalade-support.apt
  
  Index: marmalade-support.apt
  ===================================================================
    ---
    Marmalade Mojo Support - Notes
    ---
    John Casey
    ---
    07-Feb-2005
    ---
    
  *Abstract
  
    This document will track the design and implementation issues involved in 
    adding support to m2 for marmalade-based mojos.
    
  *Design Notes
  
    [[1]] <<Marmalade mojo descriptor specification.>>
    
          As in all mojo specifications, it is ideal that the descriptor for
          a marmalade-based mojo be inline with the source code. This centralizes
          all maintenance related to a single mojo to a single point of maintenance.
          
          The following is what I'm thinking as of now:
          
          - a marmalade-based mojo should look something like:
          
  +---+
          <mojo xmlns="m2:mojo" xmlns:doco="marmalade:doco">
          
            <metadata>
              <id>mmld</id>
              <name>mmldCompile</name>
              <lifecyclePhase>compile</lifecyclePhase>
              
              <doco:description>
                Used to compile marmalade scripts into java beans.
              </doco:description>
              
              <requiresDependencyResolution/>
              <instantiationStrategy/>
              <executionStrategy/>
              
              <parameters>
              
                <parameter>
                  <name>classpath</name>
                  <description>The compilation classpath</description>
                  <type>java.util.List</type>
                  <expression>#pom.artifacts</expression>
                  
                  <required/>
                  <validator/>
                  <default/>
                  
                </parameter>
                
              </parameters>
              
            </metadata>
            
            <execute>
              <!-- Do some stuff. -->
            </execute>
            
          </mojo>
  +---+
  
    [[2]] <<Marmalade mojo packager.>>
    
          The marmalade mojo packager will:
          
          [[a]] Locate all *.mmld files within the scripts directory of the project.
          
          [[b]] For each script found:
          
                [[i]]   Execute the script with "gatherMetadata=true" in the context.
                
                [[ii]]  Retrieve the mojo descriptor from the "descriptor" variable
                        in the context.
                       
                [[iii]] Add the relative script path to the mojo descriptor.
                
                [[iv]]  Cache the mojo descriptor for later aggregation.
                
          [[c]] Use the project's dependencies and other info to form the plugin
                descriptor's header (non-mojo-specific info).
                
          [[d]] Use the PluginGenerator from maven-plugin-tools to generate a
                META-INF/plexus/plugin.xml to the target directory.
                
          [[e]] Copy all scripts to the target directory. Preserve relative paths.
          
          [[f]] Package into a jar and deploy to the repo.
          
    [[3]] <<Marmalade mojo loader.>>
    
          The marmalade mojo loader will:
          
          [[a]] Retrieve the implementation spec (this is the path of the script,
                relative to the root of the plugin filesystem...jar, etc.) to 
                $path.
                
          [[b]] Use the context classloader to retrieve a reader to $path.
          
          [[c]] Build the ScriptBuilder corresponding to the script.
          
          [[d]] Create a new MarmaladeMojo instance which adapts the mojo calling
                semantics to the creation/execution of a marmalade script.
                
                Execution involves:
                
                [[i]]   Creating a new MarmaladeScript instance.
                
                [[ii]]  Creating an execution context which references all I/O
                        from the main Maven execution thread, and embeds:
                        
                        - #request == MavenExecutionRequest
                        
                        - #response == MavenExecutionResponse
                        
                        - Any globally configured environmental constraints, such
                          as a global preserve-whitespace setting
                          
                [[iii]] Execution of the script using the execution context.
                
                [[iv]]  Export of the resulting context, minus any surviving input
                        variables, to the MavenExecutionResponse's out-params.
  
  *Implementation Issues
  
    [[1]] How do we make Maven smart enough to switch loader implementations based
          on some sub-type of maven-plugin? 
          
          This is important, since the default mojo loader will not be smart 
          enough to do the job, and embedding this behavior in that loader is not 
          scalable or extensible enough to accommodate future expansion into the
          realms of jython, groovy, etc...
          
    [[2]] How do we make the plugin:install process smart enough to switch 
          generator implementations based on some sub-type of maven-plugin?
          
          This is closely related to [1] above.
          
    [[3]] We should probably look into enforcing <<<org/apache/maven/plugins/$pluginId>>>
          namespacing for plugin generation, to avoid the case where two plugins
          are script-based, load from the context classloader, depend on one 
          another's APIs, and have script names that collide.
          
          <<Example:>> An aspectWerkz plugin which provides a "/compile.mmld" and 
          depends on an eclipseCompiler plugin, which also happens to provide a
          "/compile.mmld". The AW plugin might require a java compiler to outsource
          the actual java code compilation, and want to use the Eclipse compiler
          APIs to do this. Maybe the eclipseCompiler plugin has additional 
          convenience APIs that the AW plugin wants to use...anyway, the mojo
          loader for marmalade scripts is based on classpath resources, so when
          it looks up "/compile.mmld" in the classloader for the plugin's realm, 
          will it come up with the correct script (the AW one)? This doesn't seem
          to be deterministic. It's simple to avoid this, in the same way that
          java source code does. Placing a naming constraint on scripts within a
          plugin would allow us to enforce compatibility to some extent.
          
    [[4]] Do we want to allow mixed-bag plugin implementations? 
    
          These might include a mix of standard-java and marmalade mojos. It 
          strikes me that many  marmalade-based mojos may use beans/tags that are 
          actually adapter classes for other third-party APIs (why they wouldn't 
          implement everything as java mojos in this cases is beyond me). If they 
          have java source inside the plugin source directory, we should probably 
          compile it and bundle it with the plugin scripts; but what if this source
          also has mojo annotations? This will have implications for [1] and [2] 
          above.
  
  
  

Re: cvs commit: maven-components/maven-core/src/site/apt/scripting-support marmalade-support.apt

Posted by John Casey <jd...@commonjava.org>.
fyi, when we address language support, we'll probably have to address 
something similar to <sourceModifications/> since it's entirely possible 
that a marmalade scripts can import one another like JSPs...meaning that 
it's also plausible to have "component" marmalade scripts that perform 
one common action in a reusable way, and have that "component" imported 
into multiple mojo scripts. The component script wouldn't be a mojo 
script, and therefore would cause the mojo-generation process to puke.

To solve this problem, I'd make a sourceModification that excluded all 
scripts in **/components or somesuch.

John Casey wrote:
> 
> 
> Brett Porter wrote:
> 
>>>
>>> Another option to implement the descriptor annotations for 
>>> non-marmalade (that is, java-syntax-based) might be to have a base 
>>> class or interface from which all mojo scripts inherit. I've looked 
>>> around, and this is technically possible in janino and beanshell, and 
>>> jason tells me it's possible in groovy as well. One thing about 
>>> creating a GUI mojo editor is that unless we're going to provide 
>>> syntactic support for all of our supported mojo scripting languages, 
>>> it's not going to bring much value...
>>
>>
>>
>> Right, but if someone else provides support for said language (at 
>> least groovy are pushing this), then it'd be good if we don't have to 
>> do additional work on top of that.
>>
> 
> Presumably, if someone writes support for a scripting language it'd 
> support the same constructs and syntax that the language itself 
> supports...so that would make our job as easy as proving a 
> script-template with the appropriate methods and/or class declarations...
> 
> I'm basically indifferent on this part, provided we can include the mojo 
> markup inline with the source. I really do think it'll make the 
> developer's life easier, and the mojos themselves easier to intuit and 
> maintain.

Re: cvs commit: maven-components/maven-core/src/site/apt/scripting-support marmalade-support.apt

Posted by John Casey <jd...@commonjava.org>.

Brett Porter wrote:
>>
>> Another option to implement the descriptor annotations for 
>> non-marmalade (that is, java-syntax-based) might be to have a base 
>> class or interface from which all mojo scripts inherit. I've looked 
>> around, and this is technically possible in janino and beanshell, and 
>> jason tells me it's possible in groovy as well. One thing about 
>> creating a GUI mojo editor is that unless we're going to provide 
>> syntactic support for all of our supported mojo scripting languages, 
>> it's not going to bring much value...
> 
> 
> Right, but if someone else provides support for said language (at least 
> groovy are pushing this), then it'd be good if we don't have to do 
> additional work on top of that.
> 

Presumably, if someone writes support for a scripting language it'd 
support the same constructs and syntax that the language itself 
supports...so that would make our job as easy as proving a 
script-template with the appropriate methods and/or class declarations...

I'm basically indifferent on this part, provided we can include the mojo 
markup inline with the source. I really do think it'll make the 
developer's life easier, and the mojos themselves easier to intuit and 
maintain.

Re: cvs commit: maven-components/maven-core/src/site/apt/scripting-support marmalade-support.apt

Posted by Brett Porter <br...@apache.org>.
John Casey wrote:

> See inlined comments. Since it seems that we're both in basic 
> agreement, I'll proceed with this general plan and make adjustments 
> where need be later.

Sounds good.

>
> So what you're saying is put in some type of comment with embedded XML 
> for things like janino, beanshell, and groovy? Then, I suppose we 
> could put a parser in place that's non-specific to any type of script, 
> providing we can tie each type to a component-factory reliably...

urgh! No, not really :) I meant there's a case for having the xml 
metadata separate from the script. I'm not passionate about this either 
way, and I think its fine to include in the script for marmalade and we 
can consider more when we get to the next scripting language (I feel 
beanshell or javascript may be the best next one?). Just don't put any 
roadblocks to having it separate :)

>
> Another option to implement the descriptor annotations for 
> non-marmalade (that is, java-syntax-based) might be to have a base 
> class or interface from which all mojo scripts inherit. I've looked 
> around, and this is technically possible in janino and beanshell, and 
> jason tells me it's possible in groovy as well. One thing about 
> creating a GUI mojo editor is that unless we're going to provide 
> syntactic support for all of our supported mojo scripting languages, 
> it's not going to bring much value...

Right, but if someone else provides support for said language (at least 
groovy are pushing this), then it'd be good if we don't have to do 
additional work on top of that.

>>
>> I'd still like to consider the use of attributes in this sort of area 
>> if possible to make it less verbose.
>
>
> I've always been in favor of using xml attributes for this type of 
> stuff, but if we're not changing the POM syntax, I'd oppose this. It 
> will only confuse developers if we're inconsistent.

Right, I see what you mean. There's a point - does this stuff belong in 
the POM? Hmm... the answer to that is probably whether the information 
is needed without downloading/loading the plugin.

>>>
>>>
>> src/main/mmld ?
>
>
> Do we provide <marmaladeSourceDirectory/>? If so, should we think 
> about binding this setting to the marmalade-mojo mojos, to make the 
> POM scale a little better? I'd hate to have to include 
> <janinoSourceDirectory/>, <beanshellSourceDirectory/> and 
> <groovySourceDirectory/>...

I need to push out another document I have that just allows multiple 
languages in the POM. marmaladeSourceDirectory might be fine for now?

>
> This is a little harder, unless we're going to have mojo developers 
> bind the specific generators to part of the lifecycle...and even then, 
> we need to setup some inter-generator aggregator for MojoDescriptor's, 
> so that at the end of the generation lifecycle phase we can puke one 
> plugin descriptor file out to META-INF/maven/plugin.xml. We can 
> provide a default lifecycle with all generators bound, but we still 
> have the same problem with aggregation of all generated mojo descriptors.

Right, I see where you are coming from. This, like the previous one, get 
to the heart of the lifecycle stuff we are discussing. Perhaps for now, 
we can allow a little hardwiring with a note to incorporate this when we 
come back?

Thanks John!

Cheers,
Brett

Re: cvs commit: maven-components/maven-core/src/site/apt/scripting-support marmalade-support.apt

Posted by John Casey <jd...@commonjava.org>.
See inlined comments. Since it seems that we're both in basic agreement, 
I'll proceed with this general plan and make adjustments where need be 
later.

Brett Porter wrote:
>>          As in all mojo specifications, it is ideal that the 
>> descriptor for
>>          a marmalade-based mojo be inline with the source code. This 
>> centralizes
>>          all maintenance related to a single mojo to a single point of 
>> maintenance.
>>  
>>
> Is this potentially a problem in that we have to have so many ways of 
> configuring different types of scripts. It may not be at all appropriate 
> for some to do it in their native language.
> While the javadoc style works great for Java ones, I wonder if a generic 
> XML one might be helpful. In marmalade, this can still be inlined using 
> namespaces as you have done.
> Another reason is that this will mean we can make a more generic plugin 
> metadata GUI editor.
> 

So what you're saying is put in some type of comment with embedded XML 
for things like janino, beanshell, and groovy? Then, I suppose we could 
put a parser in place that's non-specific to any type of script, 
providing we can tie each type to a component-factory reliably...

Another option to implement the descriptor annotations for non-marmalade 
(that is, java-syntax-based) might be to have a base class or interface 
from which all mojo scripts inherit. I've looked around, and this is 
technically possible in janino and beanshell, and jason tells me it's 
possible in groovy as well. One thing about creating a GUI mojo editor 
is that unless we're going to provide syntactic support for all of our 
supported mojo scripting languages, it's not going to bring much value...


>>                       <requiresDependencyResolution/>
>>  
>>
> If using this, I'd make it a boolean element rather than test existence. 
> Modello probably likes it better anyway :)

Yeah, that's just John-speak for "optional element". I'd definitely 
prefer some way of specifying a concrete boolean value for these.

> 
> I'd still like to consider the use of attributes in this sort of area if 
> possible to make it less verbose.

I've always been in favor of using xml attributes for this type of 
stuff, but if we're not changing the POM syntax, I'd oppose this. It 
will only confuse developers if we're inconsistent.

> 
> Other than that, this looks good.
> 
>>  
>>    [[2]] <<Marmalade mojo packager.>>
>>             The marmalade mojo packager will:
>>                   [[a]] Locate all *.mmld files within the scripts 
>> directory of the project.
>>  
>>
> src/main/mmld ?

Do we provide <marmaladeSourceDirectory/>? If so, should we think about 
binding this setting to the marmalade-mojo mojos, to make the POM scale 
a little better? I'd hate to have to include <janinoSourceDirectory/>, 
<beanshellSourceDirectory/> and <groovySourceDirectory/>...

> 
>>  *Implementation Issues
>>  
>>    [[1]] How do we make Maven smart enough to switch loader 
>> implementations based
>>          on some sub-type of maven-plugin?  
>>
> Ok, this is superficial, but as I understand it, each mojo is 
> independant, and a plugin is a block of mojos. So a plugin is just one 
> type and can record the language of each mojo, and execute using the 
> appropriate loader?

Yeah, that's definitely something we could code into the plugin loader. 
I guess we'd have to hand the plugin loader a mapping of 
languages-to-mojoLoaders, but that's no real problem.

> 
>>    [[2]] How do we make the plugin:install process smart enough to 
>> switch          generator implementations based on some sub-type of 
>> maven-plugin?
>>  
>>
> as above

This is a little harder, unless we're going to have mojo developers bind 
the specific generators to part of the lifecycle...and even then, we 
need to setup some inter-generator aggregator for MojoDescriptor's, so 
that at the end of the generation lifecycle phase we can puke one plugin 
descriptor file out to META-INF/maven/plugin.xml. We can provide a 
default lifecycle with all generators bound, but we still have the same 
problem with aggregation of all generated mojo descriptors.

> 
>>             [[3]] We should probably look into enforcing 
>> <<<org/apache/maven/plugins/$pluginId>>>
>>          namespacing for plugin generation, to avoid the case where 
>> two plugins
>>          are script-based, load from the context classloader, depend 
>> on one          another's APIs, and have script names that collide.
>>  
>>
> I'm confused by this. I thought each plugin's classloader was separated, 
> and deep integration such as what you talk about for aspectwerkz is not 
> on. If AW needs to use some shared services, it would need to depend on 
> a JAR, which may contain Java or some other Marmalade script as long as 
> MMLD knows how to exec it, but never cross reference code from another 
> running plugin.
> 

We'll strike it from the record, then. :)

>>             [[4]] Do we want to allow mixed-bag plugin implementations?  
>>
> I think so. Being able to include arbitrary Java classes that can be 
> accessed from Java Mojo's and MMLD Mojo's and so on is one thing, and I 
> think essential. The other thing is being able to have Java Mojos and 
> MMLD mojos in one script. This is less important, but still a nice to have.

Agreed.

> 
> Cheers,
> Brett
> 
> 
> 

Re: cvs commit: maven-components/maven-core/src/site/apt/scripting-support marmalade-support.apt

Posted by Brett Porter <br...@apache.org>.
Hi John,

This is looking pretty good!

I'll let you own the document, but here are my thoughts.

jdcasey@apache.org wrote:

>          As in all mojo specifications, it is ideal that the descriptor for
>          a marmalade-based mojo be inline with the source code. This centralizes
>          all maintenance related to a single mojo to a single point of maintenance.
>  
>
Is this potentially a problem in that we have to have so many ways of 
configuring different types of scripts. It may not be at all appropriate 
for some to do it in their native language.
While the javadoc style works great for Java ones, I wonder if a generic 
XML one might be helpful. In marmalade, this can still be inlined using 
namespaces as you have done.
Another reason is that this will mean we can make a more generic plugin 
metadata GUI editor.

>          
>              <requiresDependencyResolution/>
>  
>
If using this, I'd make it a boolean element rather than test existence. 
Modello probably likes it better anyway :)

I'd still like to consider the use of attributes in this sort of area if 
possible to make it less verbose.

Other than that, this looks good.

>  
>    [[2]] <<Marmalade mojo packager.>>
>    
>          The marmalade mojo packager will:
>          
>          [[a]] Locate all *.mmld files within the scripts directory of the project.
>  
>
src/main/mmld ?

>  *Implementation Issues
>  
>    [[1]] How do we make Maven smart enough to switch loader implementations based
>          on some sub-type of maven-plugin? 
>  
>
Ok, this is superficial, but as I understand it, each mojo is 
independant, and a plugin is a block of mojos. So a plugin is just one 
type and can record the language of each mojo, and execute using the 
appropriate loader?

>    [[2]] How do we make the plugin:install process smart enough to switch 
>          generator implementations based on some sub-type of maven-plugin?
>  
>
as above

>          
>    [[3]] We should probably look into enforcing <<<org/apache/maven/plugins/$pluginId>>>
>          namespacing for plugin generation, to avoid the case where two plugins
>          are script-based, load from the context classloader, depend on one 
>          another's APIs, and have script names that collide.
>  
>
I'm confused by this. I thought each plugin's classloader was separated, 
and deep integration such as what you talk about for aspectwerkz is not 
on. If AW needs to use some shared services, it would need to depend on 
a JAR, which may contain Java or some other Marmalade script as long as 
MMLD knows how to exec it, but never cross reference code from another 
running plugin.

>          
>    [[4]] Do we want to allow mixed-bag plugin implementations? 
>  
>
I think so. Being able to include arbitrary Java classes that can be 
accessed from Java Mojo's and MMLD Mojo's and so on is one thing, and I 
think essential. The other thing is being able to have Java Mojos and 
MMLD mojos in one script. This is less important, but still a nice to have.

Cheers,
Brett