You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2020/03/03 21:46:29 UTC

[maven] branch MNG-6656 updated: [MNG-6656] Changes based on review comments. Introduce AbstractModelSourceTransformer to have 1 class for transforming pom files.

This is an automated email from the ASF dual-hosted git repository.

rfscholte pushed a commit to branch MNG-6656
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/MNG-6656 by this push:
     new e0093d5  [MNG-6656] Changes based on review comments. Introduce AbstractModelSourceTransformer to have 1 class for transforming pom files.
e0093d5 is described below

commit e0093d56bbfe31115b6d9027cede43848a4c4221
Author: rfscholte <rf...@apache.org>
AuthorDate: Tue Mar 3 22:46:19 2020 +0100

    [MNG-6656] Changes based on review comments.
    Introduce AbstractModelSourceTransformer to have 1 class for transforming pom files.
---
 .../maven/project/DefaultProjectBuilder.java       | 167 +++++++-----------
 .../org/apache/maven/project/ReactorModelPool.java |  13 +-
 .../building/AbstractModelSourceTransformer.java   | 194 +++++++++++++++++++++
 .../maven/model/building/DefaultModelBuilder.java  |   2 +-
 .../building/DefaultModelSourceTransformer.java    |  60 ++-----
 .../model/building/ModelSourceTransformer.java     |   7 +-
 ...eTransformer.java => TransformerException.java} |  26 +--
 .../apache/maven/model/io/DefaultModelReader.java  |   6 +-
 .../xml/sax/filter/ConsumerPomXMLFilterTest.java   |   8 +-
 9 files changed, 305 insertions(+), 178 deletions(-)

diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
index ece4719..4b9821a 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
@@ -20,12 +20,9 @@ package org.apache.maven.project;
  */
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.AbstractMap;
 import java.util.ArrayList;
@@ -38,10 +35,7 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
-import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
@@ -49,12 +43,8 @@ import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.sax.SAXSource;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
 
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.Artifact;
@@ -73,6 +63,7 @@ import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.Profile;
 import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.building.AbstractModelSourceTransformer;
 import org.apache.maven.model.building.ArtifactModelSource;
 import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory;
 import org.apache.maven.model.building.DefaultModelBuildingRequest;
@@ -91,7 +82,6 @@ import org.apache.maven.model.resolution.ModelResolver;
 import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
 import org.apache.maven.xml.Factories;
 import org.apache.maven.xml.sax.filter.AbstractSAXFilter;
-import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
 import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
@@ -109,7 +99,6 @@ import org.eclipse.aether.resolution.ArtifactRequest;
 import org.eclipse.aether.resolution.ArtifactResult;
 import org.eclipse.aether.transform.FileTransformer;
 import org.eclipse.aether.transform.TransformException;
-import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
@@ -934,7 +923,7 @@ public class DefaultProjectBuilder
                 DeploymentRepository r = project.getDistributionManagement().getRepository();
                 if ( !StringUtils.isEmpty( r.getId() ) && !StringUtils.isEmpty( r.getUrl() ) )
                 {
-                    ArtifactRepository repo = repositorySystem.buildArtifactRepository( r );
+                    ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository( r );
                     repositorySystem.injectProxy( projectBuildingRequest.getRepositorySession(),
                                                   Arrays.asList( repo ) );
                     repositorySystem.injectAuthentication( projectBuildingRequest.getRepositorySession(),
@@ -958,7 +947,7 @@ public class DefaultProjectBuilder
                 DeploymentRepository r = project.getDistributionManagement().getSnapshotRepository();
                 if ( !StringUtils.isEmpty( r.getId() ) && !StringUtils.isEmpty( r.getUrl() ) )
                 {
-                    ArtifactRepository repo = repositorySystem.buildArtifactRepository( r );
+                    ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository( r );
                     repositorySystem.injectProxy( projectBuildingRequest.getRepositorySession(),
                                                   Arrays.asList( repo ) );
                     repositorySystem.injectAuthentication( projectBuildingRequest.getRepositorySession(),
@@ -1122,56 +1111,20 @@ public class DefaultProjectBuilder
         Collection<FileTransformer> transformers = new ArrayList<>();
         if ( "pom".equals( artifact.getExtension() ) )
         {
-            final SAXTransformerFactory transformerFactory =
-                (SAXTransformerFactory) Factories.newTransformerFactory();
-            
             transformers.add( new FileTransformer()
             {
                 @Override
-                public InputStream transformData( File file )
+                public InputStream transformData( File pomFile )
                     throws IOException, TransformException
                 {
-                    final PipedOutputStream pipedOutputStream  = new PipedOutputStream();
-                    final PipedInputStream pipedInputStream  = new PipedInputStream( pipedOutputStream );
-                    
-                    final TransformerHandler transformerHandler =
-                        getTransformerHandler( transformerFactory, file );
-                    
-                    BuildPomXMLFilterFactory buildPomXmlFactory = new DefaultBuildPomXMLFilterFactory( context );
-                    
-                    final SAXSource transformSource;
                     try
                     {
-                        AbstractSAXFilter filter =
-                            new ConsumerPomXMLFilterFactory( buildPomXmlFactory ).get( file.toPath() );
-                        filter.setLexicalHandler( transformerHandler );
-                        
-                        transformSource =
-                            new SAXSource( filter, new InputSource( new FileInputStream( file ) ) );
-                    }
-                    catch ( SAXException | ParserConfigurationException | TransformerConfigurationException e )
-                    {   
-                        throw new TransformException( "Failed to create a consumerPomXMLFilter", e );
+                        return new ConsumerModelSourceTransformer().transform( pomFile.toPath(), context );
                     }
-                    
-                    transformerHandler.setResult( new StreamResult( pipedOutputStream ) );
-                    
-                    SAXResult transformResult = new SAXResult( transformerHandler );
-                    
-                    ExecutorService executorService = Executors.newSingleThreadExecutor();
-                    executorService.execute( () -> 
+                    catch ( org.apache.maven.model.building.TransformerException e )
                     {
-                        try ( PipedOutputStream out = pipedOutputStream )
-                        {
-                            transformerFactory.newTransformer().transform( transformSource, transformResult );
-                        }
-                        catch ( TransformerException | IOException e )
-                        {
-                            throw new RuntimeException( e );
-                        }
-                    } );
-
-                    return pipedInputStream;
+                        throw new TransformException( e );
+                    }
                 }
                 
                 @Override
@@ -1184,51 +1137,6 @@ public class DefaultProjectBuilder
         }
         return Collections.unmodifiableCollection( transformers );
     }
-    
-    private static TransformerHandler getTransformerHandler( SAXTransformerFactory transformerFactory,
-                                                             File file )
-               throws IOException, FileNotFoundException, TransformException
-           {
-               final TransformerHandler transformerHandler;
-               
-               // Keep same encoding+version
-               try ( FileInputStream input = new FileInputStream( file ) )
-               {
-                   XMLStreamReader streamReader =
-                       XMLInputFactory.newFactory().createXMLStreamReader( input );
-
-                   transformerHandler = transformerFactory.newTransformerHandler();
-
-                   final String encoding = streamReader.getCharacterEncodingScheme();
-                   final String version = streamReader.getVersion();
-                   
-                   Transformer transformer = transformerHandler.getTransformer();
-                   if ( encoding == null && version == null )
-                   {
-                       transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" );
-                   }
-                   else
-                   {
-                       transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" );
-
-                       if ( encoding != null )
-                       {
-                           transformer.setOutputProperty( OutputKeys.ENCODING, encoding );
-                       }
-                       if ( version != null )
-                       {
-                           transformer.setOutputProperty( OutputKeys.VERSION, version );
-                       }
-                   }
-               }
-               catch ( XMLStreamException 
-                               | FactoryConfigurationError
-                               | TransformerConfigurationException e )
-               {
-                   throw new TransformException( "Failed to detect XML encoding and version", e );
-               }
-               return transformerHandler;
-           }
 
     /**
      * InternalConfig
@@ -1259,6 +1167,63 @@ public class DefaultProjectBuilder
 
     }
 
+    static class ConsumerModelSourceTransformer extends AbstractModelSourceTransformer
+    {
+        @Override
+        protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context )
+            throws TransformerConfigurationException, SAXException, ParserConfigurationException
+        {
+            return new ConsumerPomXMLFilterFactory( new DefaultBuildPomXMLFilterFactory( context ) ).get( pomFile );
+        }
+        
+        @Override
+        protected TransformerHandler getTransformerHandler( Path pomFile )
+            throws IOException, org.apache.maven.model.building.TransformerException
+        {
+            final TransformerHandler transformerHandler;
+            
+            final SAXTransformerFactory transformerFactory =
+                            (SAXTransformerFactory) Factories.newTransformerFactory();
+            
+            // Keep same encoding+version
+            try ( InputStream input = Files.newInputStream( pomFile ) )
+            {
+                XMLStreamReader streamReader =
+                    XMLInputFactory.newFactory().createXMLStreamReader( input );
+
+                transformerHandler = transformerFactory.newTransformerHandler();
+
+                final String encoding = streamReader.getCharacterEncodingScheme();
+                final String version = streamReader.getVersion();
+                
+                Transformer transformer = transformerHandler.getTransformer();
+                if ( encoding == null && version == null )
+                {
+                    transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" );
+                }
+                else
+                {
+                    transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" );
+
+                    if ( encoding != null )
+                    {
+                        transformer.setOutputProperty( OutputKeys.ENCODING, encoding );
+                    }
+                    if ( version != null )
+                    {
+                        transformer.setOutputProperty( OutputKeys.VERSION, version );
+                    }
+                }
+            }
+            catch ( XMLStreamException | TransformerConfigurationException e )
+            {
+                throw new org.apache.maven.model.building.TransformerException( 
+                                   "Failed to detect XML encoding and version", e );
+            }
+            return transformerHandler;
+        }
+    }
+
     private ReactorModelCache getModelCache()
     {
         return this.modelCache;
diff --git a/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java b/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
index 6410110..3a788e6 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
@@ -36,7 +36,7 @@ import org.apache.maven.model.Model;
  * reactor when building another project's effective model.
  *
  * @author Benjamin Bentmann
- * @Robert Scholte
+ * @author Robert Scholte
  */
 class ReactorModelPool
 {
@@ -45,12 +45,12 @@ class ReactorModelPool
     private final Map<Path, Model> modelsByPath = new HashMap<>();
 
     /**
-     * This used to be the only method, which  
+     * Get the model by its GAV or (since 3.7.0) by its GA if there is only one.
      *  
      * @param groupId, never {@code null}
      * @param artifactId, never {@code null}
      * @param version, can be {@code null}
-     * @return the matching model
+     * @return the matching model or {@code null}
      * @throws IllegalStateException if version was null and multiple modules share the same groupId + artifactId
      * @throws NoSuchElementException if model could not be found
      */
@@ -66,6 +66,13 @@ class ReactorModelPool
                         } ).orElse( null );
     }
 
+    /**
+     * Find model by path, useful when location the parent by relativePath
+     * 
+     * @param path
+     * @return the matching model or {@code null}
+     * @since 3.7.0
+     */
     public Model get( Path path )
     {
         final Path pomFile;
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java
new file mode 100644
index 0000000..db26715
--- /dev/null
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java
@@ -0,0 +1,194 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.FileInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.nio.file.Path;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.maven.xml.Factories;
+import org.apache.maven.xml.sax.filter.AbstractSAXFilter;
+import org.xml.sax.SAXException;
+
+/**
+ * 
+ * @author Robert Scholte
+ * @since 3.7.0
+ */
+public abstract class AbstractModelSourceTransformer
+    implements ModelSourceTransformer
+{
+    private static final AtomicInteger TRANSFORM_THREAD_COUNTER = new AtomicInteger();
+    
+    private final TransformerFactory transformerFactory = Factories.newTransformerFactory();
+                    
+    protected abstract AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context )
+        throws TransformerConfigurationException, SAXException, ParserConfigurationException;
+
+    protected OutputStream filterOutputStream( OutputStream outputStream, Path pomFile )
+    {
+        return outputStream;
+    }
+    
+    protected TransformerHandler getTransformerHandler( Path pomFile )
+        throws IOException, org.apache.maven.model.building.TransformerException
+    {
+        return null;
+    }
+
+    @Override
+    public final InputStream transform( Path pomFile, TransformerContext context )
+        throws IOException, org.apache.maven.model.building.TransformerException
+    {
+        final TransformerHandler transformerHandler = getTransformerHandler( pomFile );
+
+        final AbstractSAXFilter filter;
+        try
+        {
+            filter = getSAXFilter( pomFile, context );
+            filter.setLexicalHandler( transformerHandler );
+        }
+        catch ( TransformerConfigurationException | SAXException | ParserConfigurationException e )
+        {
+            throw new org.apache.maven.model.building.TransformerException( e );
+        }
+        
+        final SAXSource transformSource =
+            new SAXSource( filter,
+                           new org.xml.sax.InputSource( new FileInputStream( pomFile.toFile() ) ) );
+
+        final PipedOutputStream pout = new PipedOutputStream();
+        final PipedInputStream pipedInputStream = new PipedInputStream( pout );
+        
+        OutputStream out = filterOutputStream( pout, pomFile );
+
+        final javax.xml.transform.Result result; 
+        if ( transformerHandler == null )
+        {
+            result = new StreamResult( out );
+        }
+        else
+        {
+            transformerHandler.setResult( new StreamResult( out ) );
+            result = new SAXResult( transformerHandler ); 
+        }
+
+        IOExceptionHandler eh = new IOExceptionHandler();
+
+        Thread transformThread = new Thread( () -> 
+        {
+            try ( PipedOutputStream pos = pout )
+            {
+                transformerFactory.newTransformer().transform( transformSource, result );
+            }
+            catch ( TransformerException | IOException e )
+            {
+                eh.uncaughtException( Thread.currentThread(), e );
+            }
+        }, "TransformThread-" + TRANSFORM_THREAD_COUNTER.incrementAndGet() );
+        transformThread.setUncaughtExceptionHandler( eh );
+        transformThread.setDaemon( true );
+        transformThread.start();
+
+        return new ThreadAwareInputStream( pipedInputStream, eh );
+    }
+
+    private static class IOExceptionHandler
+        implements Thread.UncaughtExceptionHandler, AutoCloseable
+    {
+        private volatile Throwable cause;
+
+        @Override
+        public void uncaughtException( Thread t, Throwable e )
+        {
+            try
+            {
+                throw e;
+            }
+            catch ( TransformerException | IOException | RuntimeException | Error allGood )
+            {
+                // all good
+                this.cause = e;
+            }
+            catch ( Throwable notGood )
+            {
+                throw new AssertionError( "Unexpected Exception", e );
+            }
+        }
+
+        @Override
+        public void close()
+            throws IOException
+        {
+            if ( cause != null )
+            {
+                try
+                {
+                    throw cause;
+                }
+                catch ( IOException | RuntimeException | Error e )
+                {
+                    throw e;
+                }
+                catch ( Throwable t )
+                {
+                    throw new AssertionError();
+                }
+            }
+        }
+    }
+
+    private class ThreadAwareInputStream
+        extends FilterInputStream
+    {
+        final IOExceptionHandler h;
+
+        protected ThreadAwareInputStream( InputStream in, IOExceptionHandler h )
+        {
+            super( in );
+            this.h = h;
+        }
+
+        @Override
+        public void close()
+            throws IOException
+        {
+            try ( IOExceptionHandler eh = h )
+            {
+                super.close();
+            }
+        }
+    }
+}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index ff7fb91..9b6c5d8 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -1551,7 +1551,7 @@ public class DefaultModelBuilder
     }
 
     /**
-     * As long is Maven controls the BuildPomXMLFilter, the entities that need merging is known.
+     * As long as Maven controls the BuildPomXMLFilter, the entities that need merging are known.
      * All others can simply be copied from source to target to restore the locationTracker 
      * 
      * @author Robert Scholte
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java
index a964754..f410551 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java
@@ -19,13 +19,9 @@ package org.apache.maven.model.building;
  * under the License.
  */
 
-import java.io.FileInputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
 import java.nio.file.Path;
 
 import javax.inject.Inject;
@@ -33,12 +29,8 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.sax.SAXSource;
-import javax.xml.transform.stream.StreamResult;
 
-import org.apache.maven.xml.Factories;
+import org.apache.maven.xml.sax.filter.AbstractSAXFilter;
 import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
 import org.apache.maven.xml.sax.filter.BuildPomXMLFilterListener;
 import org.eclipse.sisu.Nullable;
@@ -51,30 +43,27 @@ import org.xml.sax.SAXException;
  */
 @Named
 @Singleton
-public class DefaultModelSourceTransformer implements ModelSourceTransformer
+public class DefaultModelSourceTransformer extends AbstractModelSourceTransformer
 {
     @Inject
     @Nullable
     private BuildPomXMLFilterListener xmlFilterListener;
     
-    @Override
-    public final InputStream transform( Path pomFile, TransformerContext context )
-        throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException
+    protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context )
+        throws TransformerConfigurationException, SAXException, ParserConfigurationException
     {
-        final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory( context );
-        final TransformerFactory transformerFactory = Factories.newTransformerFactory() ;
+        BuildPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory( context );
         
-        final PipedOutputStream pipedOutputStream  = new PipedOutputStream();
-        final PipedInputStream pipedInputStream  = new PipedInputStream( pipedOutputStream );
-
-        final SAXSource transformSource =
-            new SAXSource( buildPomXMLFilterFactory.get( pomFile ),
-                           new org.xml.sax.InputSource( new FileInputStream( pomFile.toFile() ) ) );
-
+        return buildPomXMLFilterFactory.get( pomFile );
+    }
+    
+    @Override
+    protected OutputStream filterOutputStream( OutputStream outputStream, Path pomFile )
+    {
         OutputStream out;
         if ( xmlFilterListener != null )
         {
-            out = new FilterOutputStream( pipedOutputStream )
+            out = new FilterOutputStream( outputStream )
             {
                 @Override
                 public void write( byte[] b, int off, int len )
@@ -87,29 +76,8 @@ public class DefaultModelSourceTransformer implements ModelSourceTransformer
         }
         else
         {
-            out = pipedOutputStream;
+            out = outputStream;
         }
-
-        final StreamResult result = new StreamResult( out );
-        
-        final Runnable runnable = new Runnable()
-        {
-            @Override
-            public void run()
-            {
-                try ( PipedOutputStream out = pipedOutputStream )
-                {
-                    transformerFactory.newTransformer().transform( transformSource, result );
-                }
-                catch ( TransformerException | IOException e )
-                {
-                    throw new RuntimeException( e );
-                }
-            }
-        };
-
-        new Thread( runnable ).start();
-
-        return pipedInputStream;
+        return out;
     }
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
index 3d215f4..2aa3ddb 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
@@ -23,11 +23,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Path;
 
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerConfigurationException;
-
-import org.xml.sax.SAXException;
-
 /**
  * 
  * @author Robert Scholte
@@ -36,5 +31,5 @@ import org.xml.sax.SAXException;
 public interface ModelSourceTransformer
 {
     InputStream transform( Path pomFile, TransformerContext context )
-        throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException;
+        throws IOException, TransformerException;
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java
similarity index 63%
copy from maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
copy to maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java
index 3d215f4..6c89d67 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java
@@ -9,7 +9,7 @@ package org.apache.maven.model.building;
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *  http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -19,22 +19,22 @@ package org.apache.maven.model.building;
  * under the License.
  */
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Path;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerConfigurationException;
-
-import org.xml.sax.SAXException;
-
 /**
  * 
  * @author Robert Scholte
  * @since 3.7.0
  */
-public interface ModelSourceTransformer
+public class TransformerException extends Exception
 {
-    InputStream transform( Path pomFile, TransformerContext context )
-        throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException;
+
+    public TransformerException( Exception e )
+    {
+        super ( e );
+    }
+
+    public TransformerException( String message, Throwable exception )
+    {
+        super( message, exception );
+    }
+
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java b/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
index 86060ae..ea0a55d 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
@@ -30,19 +30,17 @@ import java.util.Objects;
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerConfigurationException;
 
 import org.apache.maven.model.InputSource;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.building.ModelSourceTransformer;
 import org.apache.maven.model.building.TransformerContext;
+import org.apache.maven.model.building.TransformerException;
 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 import org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx;
 import org.codehaus.plexus.util.ReaderFactory;
 import org.codehaus.plexus.util.xml.XmlStreamReader;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-import org.xml.sax.SAXException;
 
 /**
  * Handles deserialization of a model from some kind of textual format like XML.
@@ -85,7 +83,7 @@ public class DefaultModelReader
             {
                 is = transformer.transform( input.toPath(), context );
             }
-            catch ( TransformerConfigurationException | SAXException | ParserConfigurationException e )
+            catch ( TransformerException e )
             {
                 throw new IOException( "Failed to transform " + input,  e );
             }
diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java
index 03cc87d..16d458b 100644
--- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java
+++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java
@@ -36,10 +36,10 @@ import org.xml.sax.SAXException;
 public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
 {
     @Override
-        protected String omitXmlDeclaration()
-        {
-            return "no";
-        }
+    protected String omitXmlDeclaration()
+    {
+        return "no";
+    }
     
     @Override
     protected AbstractSAXFilter getFilter() throws SAXException, ParserConfigurationException, TransformerConfigurationException