blob: bad3cbfcb1ae125fcb1c65ce722fb26537824d5a [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../../../favicon.ico">
<link rel="icon" type="image/png" href="../../../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../../../css/cardio.css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="preloader">
<img src="../../../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../../../docs.html">Documentation</a></li>
<li><a href="../../../../community/index.html">Community</a></li>
<li><a href="../../../../security/security.html">Security</a></li>
<li><a href="../../../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<div class='btn-toolbar pull-right' style="z-index: 2000;">
<div class='btn-group'>
<a class="btn" href="../../../../master/docs/advanced/shading/index.pdf"><i class="fa fa-file-pdf-o"></i> Download as PDF</a>
</div>
</div>
<h1>Fat / Uber jars - Using the Shade Plugin</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Shading the container and the application has some challenges like merging correctly resources (<code>META-INF/services/</code> typically).</p>
</div>
<div class="paragraph">
<p>Here is a maven shade plugin configuration working for most cases:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
&lt;version&gt;2.3&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;shade&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;dependencyReducedPomLocation&gt;${project.build.directory}/reduced-pom.xml&lt;/dependencyReducedPomLocation&gt;
&lt;transformers&gt;
&lt;transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"&gt;
&lt;mainClass&gt;org.apache.tomee.embedded.FatApp&lt;/mainClass&gt;
&lt;/transformer&gt;
&lt;transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"&gt;
&lt;resource&gt;META-INF/cxf/bus-extensions.txt&lt;/resource&gt;
&lt;/transformer&gt;
&lt;transformer implementation="org.apache.openwebbeans.maven.shade.OpenWebBeansPropertiesTransformer" /&gt;
&lt;/transformers&gt;
&lt;filters&gt;
&lt;filter&gt; &lt;!-- we don't want JSF to be activated --&gt;
&lt;artifact&gt;*:*&lt;/artifact&gt;
&lt;excludes&gt;
&lt;exclude&gt;META-INF/faces-config.xml&lt;/exclude&gt;
&lt;/excludes&gt;
&lt;/filter&gt;
&lt;/filters&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.openwebbeans&lt;/groupId&gt;
&lt;artifactId&gt;openwebbeans-maven&lt;/artifactId&gt;
&lt;version&gt;1.7.0/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
see <a href="../tomee-embedded/index.html">TomEE Embedded</a> page for more information about tomee embedded options.
</td>
</tr>
</table>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
this shade uses TomEE Embedded but you can do the same with an <a href="../applicationcomposer/index.html">Application Composer</a> application.
</td>
</tr>
</table>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
if you have <code>META-INF/web-fragment.xml</code> in your application you will need to merge them in a single one in the shade. Note that tomcat provides one
which can be skipped in this operation since it is there only as a marker for jasper detection.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Then just build the jar:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">mvn clean package</code></pre>
</div>
</div>
<div class="paragraph">
<p>And you can run it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">java -jar myapp-1.0-SNAPSHOT.jar</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_fat_jars_with_gradle">Fat Jars with Gradle</h2>
<div class="sectionbody">
<div class="paragraph">
<p>With gradle you can rely on either jar plugin, fatjar plugin or shadowjar plugin. Last one is likely the closer to maven shade plugin
so that&#8217;s the one used for next sample:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-groovy" data-lang="groovy">// run $ gradle clean shadowJar
import org.apache.openwebbeans.gradle.shadow.OpenWebBeansPropertiesTransformer
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
classpath 'org.apache.openwebbeans:openwebbeans-gradle:1.7.0'
}
}
apply plugin: 'com.github.johnrengelman.shadow'
group 'org.apache.tomee.demo.gradle'
version '1.0-SNAPSHOT'
apply plugin: 'idea'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.16.10'
compile 'org.apache.tomee:tomee-embedded:7.0.2-SNAPSHOT'
}
// customize exclusions depending your app
// first the not used dependencies like JSF, JAXWS, JMS ones
def excludedDependenciesGroups = [
// gradle is buggy with poms, scope provided and optional I think
'com.google.code.findbugs',
'com.google.guava',
'javax.annotation',
'javax.ws.rs',
'net.sf.ehcache',
'org.apache.httpcomponents',
'org.ow2.asm',
// tomee jaxws, jms, etc...
'commons-codec',
'com.sun.xml.messaging.saaj',
'joda-time',
'junit',
'net.shibboleth.utilities',
'org.apache.activemq',
'org.apache.activemq.protobuf',
'org.apache.myfaces.core',
'org.apache.neethi',
'org.apache.santuario',
'org.apache.ws.xmlschema',
'org.apache.wss4j',
'org.bouncycastle',
'org.cryptacular',
'org.fusesource.hawtbuf',
'org.jasypt',
'org.jvnet.mimepull',
'org.opensaml',
'wsdl4j',
'xml-resolver'
]
// then cxf+tomee specific dependencies so we need to be more precise than the group
// to not exclude everything
def excludedDependenciesArtifacts = [
'cxf-rt-bindings-soap',
'cxf-rt-bindings-xml',
'cxf-rt-databinding-jaxb',
'cxf-rt-frontend-jaxws',
'cxf-rt-frontend-simple',
'cxf-rt-security-saml',
'cxf-rt-ws-addr',
'cxf-rt-wsdl',
'cxf-rt-ws-policy',
'cxf-rt-ws-security',
'openejb-cxf',
'openejb-webservices',
'tomee-webservices',
'geronimo-connector',
'geronimo-javamail_1.4_mail'
]
shadowJar {
classifier = 'bundle'
// merge SPI descriptors
mergeServiceFiles()
append 'META-INF/cxf/bus-extensions.txt'
transform(OpenWebBeansPropertiesTransformer.class)
// switch off JSF + JMS + JAXWS
exclude 'META-INF/faces-config.xml'
dependencies {
exclude(dependency {
excludedDependenciesGroups.contains(it.moduleGroup) ||
excludedDependenciesArtifacts.contains(it.moduleName)
})
}
// ensure we define the expected Main (if you wrap tomee main use your own class)
manifest {
attributes 'Main-Class': 'org.apache.tomee.embedded.FatApp'
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">gradle clean build shadowJar</code></pre>
</div>
</div>
<div class="paragraph">
<p>and you&#8217;ll get <code>build/libs/demo-gradle-tomee-embedded-shade-1.0-SNAPSHOT-bundle.jar</code> ready to run with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">java -jar build/libs/demo-gradle-tomee-embedded-shade-1.0-SNAPSHOT-bundle.jar --as-war --simple-log=true</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_fat_wars">Fat Wars</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Fat Wars are executable wars. Note they can be fancy for demos but they have the drawback to put the server in web resources
at packaging time (to ensure the war is actually an executable jar) so adding a filter preventing these files to be read
can be needed if you don&#8217;t already use a web technology doing it (a servlet bound to /*).</p>
</div>
<div class="paragraph">
<p>Here how to do a fat war:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;properties&gt;
&lt;!-- can be uber (for all), jaxrs, jaxws for lighter ones --&gt;
&lt;tomee.flavor&gt;uber&lt;/tomee.flavor&gt;
&lt;/properties&gt;
&lt;dependencies&gt;
&lt;!-- ...your dependencies as usual... --&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.tomee&lt;/groupId&gt;
&lt;artifactId&gt;tomee-embedded&lt;/artifactId&gt;
&lt;classifier&gt;${tomee.flavor}&lt;/classifier&gt;
&lt;version&gt;7.0.0&lt;/version&gt;
&lt;scope&gt;provided&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;
&lt;version&gt;2.6&lt;/version&gt;
&lt;configuration&gt;
&lt;failOnMissingWebXml&gt;false&lt;/failOnMissingWebXml&gt;
&lt;archive&gt;
&lt;manifest&gt;
&lt;mainClass&gt;org.apache.tomee.embedded.Main&lt;/mainClass&gt;
&lt;/manifest&gt;
&lt;/archive&gt;
&lt;dependentWarExcludes /&gt;
&lt;overlays&gt;
&lt;overlay&gt;
&lt;groupId&gt;org.apache.tomee&lt;/groupId&gt;
&lt;artifactId&gt;tomee-embedded&lt;/artifactId&gt;
&lt;classifier&gt;${tomee.flavor}&lt;/classifier&gt;
&lt;type&gt;jar&lt;/type&gt;
&lt;excludes /&gt;
&lt;/overlay&gt;
&lt;/overlays&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then just build the war:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">mvn clean package</code></pre>
</div>
</div>
<div class="paragraph">
<p>And you can run it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">java -jar myapp-1.0-SNAPSHOT.war</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../../../js/jquery-1.11.1.min.js"></script>
<script src="../../../../js/owl.carousel.min.js"></script>
<script src="../../../../js/bootstrap.min.js"></script>
<script src="../../../../js/wow.min.js"></script>
<script src="../../../../js/typewriter.js"></script>
<script src="../../../../js/jquery.onepagenav.js"></script>
<script src="../../../../js/tree.jquery.js"></script>
<script src="../../../../js/highlight.pack.js"></script>
<script src="../../../../js/main.js"></script>
</body>
</html>