Posts mit dem Label Maven werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Maven werden angezeigt. Alle Posts anzeigen

Dienstag, 24. Mai 2011

Tycho: Creating an Eclipse P2 Mirror

This Blog post covers the creation of a P2 mirror for parts of the central Eclipse update site.

1. Downloading all necessary Eclipse packages

First of all you need to download all necessary Eclipse packages containing the plugins and features to be mirrored.
Download at least the lastest version of following packages:
  • Any Eclipse Platform SDK Build (platform doesn't matter)
  • Eclipse Delta Pack
You may download additonal packages too like:
  • Eclipse Modeling Tools (includes Incubating components) (platform doesn't matter)
  • Eclipse IDE for Java EE Developers
  • Eclipse Webtools Platform SDK (http://download.eclipse.org/webtools/downloads/)
  • Eclipse Babel Translations
  • etc. 
  • etc.
 Important: You always need a feature based version, thus the download have to contain the features and plugins folder.

2. Extract the contents
Extract all packages into a single directory. Finally you should have an Eclipse folder like this:
|- eclipse
  |- features
  |- plugins
  |- site.xml
  |- etc.

3. Create site.xml
After you prepared the eclipse folder you need to create a site.xml containing the list of features of your eclipse folder. This is a very painful work. To make it a bit easier i extended an existing tool from Lars Heinemann. You can grap a copy from https://github.com/sweber/EclipseToMavenTooling.
To run the tool just clone the git repository and run following commands from you favorite shell:
mvn clean install
java -cp target/eclipse2maven-1.0.0-SNAPSHOT.jar de.lhein.tooling.MainWindow
After this choose your eclipse folder from step 2, check the "Generate site.xml" button and git generate. After that you may copy the contents to your site.xml or save it directly into the eclipse folder.
You now have a old style eclips update site.

4. Generate P2 repository from Update Site
Next you have to create the P2 repository from the existing update site.
You can use a built-in Eclipse application to process your update site:

java -jar plugins/org.eclipse.equinox.launcher_*.jar
 -nosplash -application org.eclipse.equinox.p2.publisher.UpdateSitePublisher
 -metadataRepository file:/<location_where_the_repository_will_be_created>
 -artifactRepository file:/<location_where_the_repository_will_be_created>
 -source <the_eclipse_installation_directory_for_which_the_p2_repository_will_be_created>
-compress -publishArtifacts -addJREIU

After executing this command from any Eclipse install location (e.g. your development Eclipse >v3.5) your P2 repository is ready to go.

5. Remove external repository references (optional)
If you do not want that Eclipse or Tycho tries to resolve any other dependecy from the online Eclipse P2 repositories you have to remove the repository references from the generated P2 repository.

To do this open the content.jar located in your generated P2 repository and extract the included content.xml. Edit the content.xml and remove the reference section at the top of the file:

Before:
<?xml version='1.0' encoding='UTF-8'?>
<?metadataRepository version='1.1.0'?>
<repository name='file:/d:/tmp/repository/ - metadata' type='org.eclipse.equinox.internal.p2.metadata.repository.LocalMetadataRepository' version='1'>
  <properties size='2'>
    <property name='p2.timestamp' value='1301562918125'/>
    <property name='p2.compressed' value='true'/>
  </properties>
  <references size='36'>
    <repository uri='http://download.eclipse.org/releases/galileo' url='http://download.eclipse.org/releases/galileo' type='0' options='0'/>
    <repository uri='http://download.eclipse.org/releases/galileo' url='http://download.eclipse.org/releases/galileo' type='1' options='0'/>
    <repository uri='http://download.eclipse.org/dsdp/tm/updates/3.2' url='http://download.eclipse.org/dsdp/tm/updates/3.2' type='1' options='0'/>
<!--(...)-->
    <repository uri='http://download.eclipse.org/technology/epp/updates/1.3/' url='http://download.eclipse.org/technology/epp/updates/1.3/' type='0' options='0'/>
    <repository uri='http://download.eclipse.org/rt/rap/1.3/tooling' url='http://download.eclipse.org/rt/rap/1.3/tooling' type='1' options='0'/>
  </references>
  <units size='1706'>
    <unit id='org.eclipse.emf.compare.diff.edit' version='1.1.2.v20110202-0936'>
      <update id='org.eclipse.emf.compare.diff.edit' range='\[0.0.0,1.1.2.v20110202-0936)' severity='0'/>
      <properties size='5'>
        <property name='df_LT.providerName' value='Eclipse Modeling Project'/>
        <property name='df_LT.pluginName' value='Diff Edit Support'/>
        <property name='org.eclipse.equinox.p2.name' value='%pluginName'/>
        <property name='org.eclipse.equinox.p2.provider' value='%providerName'/>
        <property name='org.eclipse.equinox.p2.bundle.localization' value='plugin'/>
      </properties>
  </unit>
<!--(...)-->
 </units>
</repository>

After:
<?xml version='1.0' encoding='UTF-8'?>
<?metadataRepository version='1.1.0'?>
<repository name='file:/d:/tmp/repository/ - metadata' type='org.eclipse.equinox.internal.p2.metadata.repository.LocalMetadataRepository' version='1'>
  <properties size='2'>
    <property name='p2.timestamp' value='1301562918125'/>
    <property name='p2.compressed' value='true'/>
  </properties>
  <units size='1706'>
    <unit id='org.eclipse.emf.compare.diff.edit' version='1.1.2.v20110202-0936'>
      <update id='org.eclipse.emf.compare.diff.edit' range='\[0.0.0,1.1.2.v20110202-0936)' severity='0'/>
      <properties size='5'>
        <property name='df_LT.providerName' value='Eclipse Modeling Project'/>
        <property name='df_LT.pluginName' value='Diff Edit Support'/>
        <property name='org.eclipse.equinox.p2.name' value='%pluginName'/>
        <property name='org.eclipse.equinox.p2.provider' value='%providerName'/>
        <property name='org.eclipse.equinox.p2.bundle.localization' value='plugin'/>
      </properties>
  </unit>
<!--(...)-->
 </units>
</repository>
Then replace the content.xml inside the content.jar with the modified one.

Et voilà you're finished and have an Eclipse mirror for your Eclipse packages. If you want to share it with your coworkers just put it on your companies internal webserver.

Enjoy!

Montag, 14. März 2011

JAXB2 Primitive Fixer Plugin

Shortly we stumbled on creating a data binding with EclipseLink (Moxy). Moxy is the Eclipse JAXB implementation which can be tightly integrated into the eclipse runtime (keyword OSGI). After quite some work we came to the point were the binding was working fine. Suddenly we had to change the xml schema due to an requesst from another department. So we introduced default values for attributes with native xsd types like xs:int, xs:boolean or xs:float. Nothing you would expect to cause trouble.

Well, we were wrong! JAXB 2.x has a major problem with default values and primitive types. Its an major drawback in every implementation. It points out that the the generate Java classes have inconsistent getter for attributes with default values with primitive types.

Short example for a generated class (omited class overhead):
/** The property name for the value property. */
    public final static String PNAME_VALUE = "value";
    @XmlAttribute
    protected Integer value;
    /**
     * Gets the value of the value property.
     * @return possible object is {@link Integer }
     */
    public int getValue() {
        if (value == null) {
            return  75;
        } else {
            return value;
        }
    }
    /**
     * Sets the value of the value property.
     * @param value allowed object is {@link Integer }
     */
    public void setValue(Integer value) {
         this.value = value;
    }
As you can see, the getter returns an int while the setter expect an Integer. This will result in a not working Eclipse data binding (getter and setter do no match).

There is already an JIRA issue filed for this on the JAXB JIRA.
http://java.net/jira/browse/JAXB-733
However it won't be solved because it would destroy the backward compatibility of JAXB.

A suggestions was to create a JAXB XJC plugin that corrects this issue. So i did, you may grab a copy from
https://github.com/sweber/JAXB2-XJC-Primitive-Fixer-Plugin

The plugin searches for getter/setter pairs and if the setter expects a boxified primitive and the getter returns a primitive it will correct the getter to return the boxified primitive. Additional for boolean it will change the getter name from isXY to getXY (in respect to the Java bean notation).

To use it with maven just deploy the binary jar file to you repository and put it into your maven-jaxb2-plugin configuration like this:

    org.jvnet.jaxb2.maven2
    maven-jaxb2-plugin
    0.7.4
    
        
            
        
    
    
        true
        
            -Xfix-primitives
        
        
            
                de.sweber
                jaxb2-primitive-fixer-plugin
                1.0.0-SNAPSHOT
            
        
    

The argument you have to pass to XJC to get the plugin working is (like above used):
-Xfix-primitives

Hope i could solve a little problem with JAXB out there ;-)