You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2020/06/11 02:43:55 UTC

[tomee-patch-plugin] branch master created (now 2a06d9f)

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

dblevins pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-patch-plugin.git.


      at 2a06d9f  Initial code forked from https://github.com/tomitribe/jkta

This branch includes the following new commits:

     new 9a4b40e  Initial plugin layout
     new 2a06d9f  Initial code forked from https://github.com/tomitribe/jkta

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[tomee-patch-plugin] 02/02: Initial code forked from https://github.com/tomitribe/jkta

Posted by db...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-patch-plugin.git

commit 2a06d9f081c1db05164286db9149ba17c30754dc
Author: David Blevins <da...@gmail.com>
AuthorDate: Wed Jun 10 19:33:59 2020 -0700

    Initial code forked from https://github.com/tomitribe/jkta
    
    This is a temporary codebase with the goal of getting a completely
    running TomEE 8 under the jakarta namespace as soon as possible and
    without any overhead of abstractions or dealing with third-party
    libraries or third-party communities.
    
    This is intended as a stop-gap and this code base will not live
    long-term.  Any improvements will be migrated to either the Eclipse
    Transformer or Jkta, hopefully making this codebase not necessary.
---
 pom.xml                                            |  15 +-
 tomee-patch-core/pom.xml                           |  55 ++-
 .../tomee/patch/core/AnnotationTransformer.java    |  37 ++
 .../apache/tomee/patch/core/ClassTransformer.java  |  60 +++
 .../java/org/apache/tomee/patch/core/Copy.java     |  41 ++
 .../apache/tomee/patch/core/FieldTransformer.java  |  38 ++
 .../main/java/org/apache/tomee/patch/core/Is.java  |  39 ++
 .../apache/tomee/patch/core/MethodTransformer.java | 118 ++++++
 .../apache/tomee/patch/core/ModuleTransformer.java |  26 ++
 .../tomee/patch/core/SignatureTransformer.java     |  25 ++
 .../apache/tomee/patch/core/Transformation.java    | 101 +++++
 .../src/test/java/javax/ejb/Process.java           |  27 ++
 .../java/javax/enterprise/context/MockScoped.java  |  41 ++
 .../src/test/java/javax/jms/Consumer.java          |  26 ++
 .../java/javax/jms/EnterpriseBeanConsumer.java     |  28 ++
 .../test/java/javax/persistence/EntityBean.java    |  27 ++
 .../src/test/java/javax/persistence/Persist.java   |  31 ++
 .../patch/core/AnnotationTransformerTest.java      | 140 +++++++
 .../org/apache/tomee/patch/core/ArrayData.java     |  48 +++
 .../java/org/apache/tomee/patch/core/Asmifier.java | 168 ++++++++
 .../java/org/apache/tomee/patch/core/Bytecode.java |  62 +++
 .../tomee/patch/core/ClassTransformerTest.java     | 285 +++++++++++++
 .../java/org/apache/tomee/patch/core/Data.java     |  35 ++
 .../tomee/patch/core/FieldTransformerTest.java     |  95 +++++
 .../tomee/patch/core/MethodTransformerTest.java    | 445 +++++++++++++++++++++
 .../tomee/patch/core/ModuleTransformerTest.java    |  21 +
 .../java/org/apache/tomee/patch/core/Scan.java     |  70 ++++
 .../tomee/patch/core/SignatureTransformerTest.java |  38 ++
 .../org/apache/tomee/patch/core/Transform.java     |  78 ++++
 tomee-patch-plugin/pom.xml                         |  88 ++++
 .../apache/tomee/patch/plugin/TransformMojo.java   |  33 ++
 31 files changed, 2339 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index de443de..d9ceb64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,6 @@
     <relativePath><!--Resolve on repository--></relativePath>
   </parent>
 
-
   <groupId>org.apache.tomee.patch</groupId>
   <artifactId>tomee-patch-parent</artifactId>
   <packaging>pom</packaging>
@@ -84,5 +83,19 @@
     <module>tomee-patch-core</module>
     <module>tomee-patch-plugin</module>
   </modules>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.1</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
 
diff --git a/tomee-patch-core/pom.xml b/tomee-patch-core/pom.xml
index 93e381c..9ab050c 100644
--- a/tomee-patch-core/pom.xml
+++ b/tomee-patch-core/pom.xml
@@ -29,6 +29,59 @@
   </parent>
 
   <artifactId>tomee-patch-core</artifactId>
-  
+
+  <dependencies>
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>8.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm-tree</artifactId>
+      <version>8.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm-analysis</artifactId>
+      <version>8.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm-commons</artifactId>
+      <version>8.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm-util</artifactId>
+      <version>8.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.tomitribe</groupId>
+      <artifactId>tomitribe-crest</artifactId>
+      <version>0.14</version>
+    </dependency>
+    <dependency>
+      <groupId>org.tomitribe</groupId>
+      <artifactId>tomitribe-crest-xbean</artifactId>
+      <version>0.14</version>
+    </dependency>
+    <dependency>
+      <groupId>org.tomitribe</groupId>
+      <artifactId>tomitribe-util</artifactId>
+      <version>1.3.13</version>
+    </dependency>
+    <dependency>
+      <groupId>org.tomitribe.jkta</groupId>
+      <artifactId>jkta</artifactId>
+      <version>0.10</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.10</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
 </project>
 
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/AnnotationTransformer.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/AnnotationTransformer.java
new file mode 100644
index 0000000..5269b93
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/AnnotationTransformer.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+public class AnnotationTransformer extends AnnotationVisitor {
+
+    public AnnotationTransformer(final int api, final AnnotationVisitor annotationVisitor) {
+        super(api, annotationVisitor);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+        return new AnnotationTransformer(this.api, super.visitAnnotation(name, descriptor));
+    }
+
+    @Override
+    public AnnotationVisitor visitArray(final String name) {
+        return new AnnotationTransformer(this.api, super.visitArray(name));
+    }
+
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/ClassTransformer.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/ClassTransformer.java
new file mode 100644
index 0000000..64de18a
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/ClassTransformer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+public class ClassTransformer extends ClassVisitor {
+
+    private String className;
+
+    public ClassTransformer(final ClassWriter classVisitor) {
+        super(Opcodes.ASM8, classVisitor);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitAnnotation(descriptor, visible));
+    }
+
+    @Override
+    public FieldVisitor visitField(final int access, final String name, final String descriptor, final String signature, final Object value) {
+        return new FieldTransformer(this.api, super.visitField(access, name, descriptor, signature, value));
+    }
+
+    @Override
+    public MethodVisitor visitMethod(final int access, final String name, final String descriptor, final String signature, final String[] exceptions) {
+        return new MethodTransformer(this.api, super.visitMethod(access, name, descriptor, signature, exceptions));
+    }
+
+    @Override
+    public ModuleVisitor visitModule(final String name, final int access, final String version) {
+        return new ModuleTransformer(this.api, super.visitModule(name, access, version));
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+    }
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Copy.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Copy.java
new file mode 100644
index 0000000..8b7a6cf
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Copy.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+public class Copy<T> {
+    private final T from;
+    private final T to;
+
+    public Copy(final T from, final T to) {
+        this.from = from;
+        this.to = to;
+
+    }
+
+    public <Value> Copy<T> att(final Function<T, Value> getter, final BiConsumer<T, Value> setter) {
+        final Value value = getter.apply(from);
+        if (value != null) setter.accept(to, value);
+        return this;
+    }
+
+    public static <T> Copy<T> copy(final T from, T to) {
+        return new Copy<>(from, to);
+    }
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/FieldTransformer.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/FieldTransformer.java
new file mode 100644
index 0000000..af92959
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/FieldTransformer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.TypePath;
+
+public class FieldTransformer extends FieldVisitor {
+
+    public FieldTransformer(final int api, final FieldVisitor fieldVisitor) {
+        super(api, fieldVisitor);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitAnnotation(descriptor, visible));
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+    }
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Is.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Is.java
new file mode 100644
index 0000000..146c8ce
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Is.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import java.io.File;
+import java.io.FileFilter;
+
+public interface Is {
+
+    class Zip implements FileFilter {
+        @Override
+        public boolean accept(final File pathname) {
+            return pathname.isFile() && accept(pathname.getName());
+        }
+
+        public static boolean accept(final String path) {
+            if (path.endsWith(".zip")) return true;
+            if (!path.endsWith("ar")) return false; // optimization
+            return path.endsWith(".jar") ||
+                    path.endsWith(".ear") ||
+                    path.endsWith(".war") ||
+                    path.endsWith(".rar");
+        }
+    }
+}
\ No newline at end of file
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/MethodTransformer.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/MethodTransformer.java
new file mode 100644
index 0000000..8666b34
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/MethodTransformer.java
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+
+public class MethodTransformer extends MethodVisitor {
+
+    public MethodTransformer(final int api, final MethodVisitor methodVisitor) {
+        super(api, methodVisitor);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotationDefault() {
+        return new AnnotationTransformer(this.api, super.visitAnnotationDefault());
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitAnnotation(descriptor, visible));
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+    }
+
+    @Override
+    public AnnotationVisitor visitParameterAnnotation(final int parameter, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitParameterAnnotation(parameter, descriptor, visible));
+    }
+
+    @Override
+    public void visitFrame(final int type, final int numLocal, final Object[] local, final int numStack, final Object[] stack) {
+        switch (type) {
+            case -1:
+            case 0:
+//                add(bytecodeUsage, local);
+//                add(bytecodeUsage, stack);
+                break;
+            case 1:
+//                add(bytecodeUsage, local);
+                break;
+            case 2:
+                break;
+            case 3:
+                break;
+            case 4:
+//                add(bytecodeUsage, stack);
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        super.visitFrame(type, numLocal, local, numStack, stack);
+    }
+
+    @Override
+    public void visitLdcInsn(final Object cst) {
+        if (cst instanceof Integer) {
+            // ...
+        } else if (cst instanceof Float) {
+            // ...
+        } else if (cst instanceof Long) {
+            // ...
+        } else if (cst instanceof Double) {
+            // ...
+        } else if (cst instanceof String) {
+            // ...
+        } else if (cst instanceof Type) {
+            // ...
+        } else if (cst instanceof Handle) {
+            // ...
+        } else if (cst instanceof ConstantDynamic) {
+            // ...
+        } else {
+            // throw an exception
+        }
+        super.visitLdcInsn(cst);
+    }
+
+    @Override
+    public AnnotationVisitor visitInsnAnnotation(final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitInsnAnnotation(typeRef, typePath, descriptor, visible));
+    }
+
+    @Override
+    public AnnotationVisitor visitTryCatchAnnotation(final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible));
+    }
+
+    @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(final int typeRef, final TypePath typePath, final Label[] start, final Label[] end,
+                                                          final int[] index, final String descriptor, final boolean visible) {
+        return new AnnotationTransformer(this.api, super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible));
+    }
+
+
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/ModuleTransformer.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/ModuleTransformer.java
new file mode 100644
index 0000000..d295d28
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/ModuleTransformer.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.ModuleVisitor;
+
+public class ModuleTransformer extends ModuleVisitor {
+
+    public ModuleTransformer(final int api, final ModuleVisitor moduleVisitor) {
+        super(api, moduleVisitor);
+    }
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/SignatureTransformer.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/SignatureTransformer.java
new file mode 100644
index 0000000..3112a40
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/SignatureTransformer.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.signature.SignatureVisitor;
+
+public class SignatureTransformer extends SignatureVisitor {
+    public SignatureTransformer(final int api) {
+        super(api);
+    }
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java
new file mode 100644
index 0000000..8f05c8e
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.tomitribe.util.IO;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+public class Transformation {
+
+    private Transformation() {
+    }
+
+    public static File transform(final File jar) throws IOException {
+        final File tempFile = File.createTempFile(jar.getName(), ".transformed");
+
+        try (final InputStream inputStream = IO.read(jar)) {
+            try (final OutputStream outputStream = IO.write(tempFile)) {
+                scanJar(inputStream, outputStream);
+                return tempFile;
+            }
+        }
+    }
+
+    private static void scanJar(final InputStream inputStream, final OutputStream outputStream) throws IOException {
+        final ZipInputStream zipInputStream = new ZipInputStream(inputStream);
+        final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
+
+        ZipEntry oldEntry;
+        while ((oldEntry = zipInputStream.getNextEntry()) != null) {
+            // TODO: the name may be changed in transformation
+            final String path = oldEntry.getName();
+            final ZipEntry newEntry = new ZipEntry(path);
+
+            copyAttributes(oldEntry, newEntry);
+
+            zipOutputStream.putNextEntry(newEntry);
+
+            try {
+                if (path.endsWith(".class")) {
+                    scanClass(zipInputStream, zipOutputStream);
+                } else if (isZip(path)) {
+                    scanJar(zipInputStream, zipOutputStream);
+                } else {
+                    IO.copy(zipInputStream, zipOutputStream);
+                }
+            } finally {
+                zipOutputStream.closeEntry();
+            }
+        }
+        zipOutputStream.close();
+    }
+
+    private static void copyAttributes(final ZipEntry oldEntry, final ZipEntry newEntry) {
+        Copy.copy(oldEntry, newEntry)
+                .att(ZipEntry::getTime, ZipEntry::setTime)
+                .att(ZipEntry::getComment, ZipEntry::setComment)
+                .att(ZipEntry::getExtra, ZipEntry::setExtra)
+                .att(ZipEntry::getMethod, ZipEntry::setMethod)
+                .att(ZipEntry::getCreationTime, ZipEntry::setCreationTime)
+                .att(ZipEntry::getLastModifiedTime, ZipEntry::setLastModifiedTime)
+                .att(ZipEntry::getLastAccessTime, ZipEntry::setLastAccessTime);
+    }
+
+    private static boolean isZip(final String path) {
+        return Is.Zip.accept(path);
+    }
+
+    private static void scanClass(final InputStream in, final OutputStream outputStream) throws IOException {
+        final ClassWriter classWriter = new ClassWriter(Opcodes.ASM8);
+        final ClassTransformer classTransformer = new ClassTransformer(classWriter);
+        final ClassReader classReader = new ClassReader(in);
+        classReader.accept(classTransformer, 0);
+        final byte[] bytes = classWriter.toByteArray();
+        outputStream.write(bytes);
+    }
+
+}
diff --git a/tomee-patch-core/src/test/java/javax/ejb/Process.java b/tomee-patch-core/src/test/java/javax/ejb/Process.java
new file mode 100644
index 0000000..0393115
--- /dev/null
+++ b/tomee-patch-core/src/test/java/javax/ejb/Process.java
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.ejb;
+
+public class Process {
+
+    public void process(final EnterpriseBean bean) {}
+}
diff --git a/tomee-patch-core/src/test/java/javax/enterprise/context/MockScoped.java b/tomee-patch-core/src/test/java/javax/enterprise/context/MockScoped.java
new file mode 100644
index 0000000..8118d91
--- /dev/null
+++ b/tomee-patch-core/src/test/java/javax/enterprise/context/MockScoped.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package javax.enterprise.context;
+
+import javax.enterprise.util.AnnotationLiteral;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE, ElementType.TYPE_USE, ElementType.TYPE_PARAMETER, ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@NormalScope
+@Inherited
+public @interface MockScoped {
+    public static final class Literal extends AnnotationLiteral<MockScoped> implements MockScoped {
+        public static final MockScoped.Literal INSTANCE = new MockScoped.Literal();
+        private static final long serialVersionUID = 1L;
+
+        public Literal() {
+        }
+    }
+}
diff --git a/tomee-patch-core/src/test/java/javax/jms/Consumer.java b/tomee-patch-core/src/test/java/javax/jms/Consumer.java
new file mode 100644
index 0000000..7f12a84
--- /dev/null
+++ b/tomee-patch-core/src/test/java/javax/jms/Consumer.java
@@ -0,0 +1,26 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.jms;
+
+public interface Consumer<T> {
+    void accept(T t);
+}
\ No newline at end of file
diff --git a/tomee-patch-core/src/test/java/javax/jms/EnterpriseBeanConsumer.java b/tomee-patch-core/src/test/java/javax/jms/EnterpriseBeanConsumer.java
new file mode 100644
index 0000000..d7e86e4
--- /dev/null
+++ b/tomee-patch-core/src/test/java/javax/jms/EnterpriseBeanConsumer.java
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.jms;
+
+import javax.ejb.EnterpriseBean;
+
+public interface EnterpriseBeanConsumer {
+    void accept(final EnterpriseBean bean);
+}
\ No newline at end of file
diff --git a/tomee-patch-core/src/test/java/javax/persistence/EntityBean.java b/tomee-patch-core/src/test/java/javax/persistence/EntityBean.java
new file mode 100644
index 0000000..9ec4353
--- /dev/null
+++ b/tomee-patch-core/src/test/java/javax/persistence/EntityBean.java
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.persistence;
+
+import javax.ejb.EnterpriseBean;
+
+public interface EntityBean extends EnterpriseBean {
+}
diff --git a/tomee-patch-core/src/test/java/javax/persistence/Persist.java b/tomee-patch-core/src/test/java/javax/persistence/Persist.java
new file mode 100644
index 0000000..503c1f0
--- /dev/null
+++ b/tomee-patch-core/src/test/java/javax/persistence/Persist.java
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.persistence;
+
+import javax.jms.Consumer;
+
+public class Persist<T> {
+
+    public void forEach(Consumer<? super T> action) {
+
+    }
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/AnnotationTransformerTest.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/AnnotationTransformerTest.java
new file mode 100644
index 0000000..1dd71b4
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/AnnotationTransformerTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.junit.Test;
+import org.tomitribe.jkta.usage.Jar;
+import org.tomitribe.jkta.usage.Package;
+import org.tomitribe.jkta.usage.Usage;
+
+import javax.ejb.EnterpriseBean;
+import javax.ejb.LockType;
+import javax.servlet.http.HttpServlet;
+import javax.ws.rs.Path;
+
+import static org.apache.tomee.patch.core.Scan.assertUsage;
+import static org.apache.tomee.patch.core.Transform.usage;
+
+public class AnnotationTransformerTest {
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_primitive() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Data(length = 4)
+            public void get() {
+            }
+        });
+
+        assertUsage(usage);
+
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_String() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Data(name = "javax.ejb.EnterpriseBean")
+            public void m1() {
+            }
+
+            @Data(name = "javax/ejb/EnterpriseBean")
+            public void m2() {
+            }
+
+            @Data(name = "Ljavax/ejb/EnterpriseBean")
+            public void m3() {
+            }
+        });
+
+        assertUsage(usage);
+
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_Class() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Data(type = EnterpriseBean.class)
+            public void get() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitEnum() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Data(lock = LockType.WRITE)
+            public void get() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Data(path = @Path("/foo"))
+            public void get() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_WS_RS);
+
+    }
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            @ArrayData(data = @Data(path = @Path("/foo")))
+            public void m() {
+            }
+
+            @ArrayData(data = @Data(type = HttpServlet.class))
+            public void m2() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_WS_RS, Package.JAVAX_SERVLET);
+
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitArray() {
+        final Usage<Jar> usage = usage(new Object() {
+            @ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)})
+            public void m() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_WS_RS, Package.JAVAX_SERVLET);
+    }
+
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ArrayData.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ArrayData.java
new file mode 100644
index 0000000..fe1a574
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ArrayData.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.TYPE_PARAMETER;
+import static java.lang.annotation.ElementType.TYPE_USE;
+
+@Target({TYPE,
+        FIELD,
+        METHOD,
+        PARAMETER,
+        CONSTRUCTOR,
+        LOCAL_VARIABLE,
+        ANNOTATION_TYPE,
+        PACKAGE,
+        TYPE_PARAMETER,
+        TYPE_USE
+})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ArrayData {
+    Data[] data() default {};
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Asmifier.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Asmifier.java
new file mode 100644
index 0000000..1c7a26a
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Asmifier.java
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.util.ASMifier;
+import org.objectweb.asm.util.TraceClassVisitor;
+import org.tomitribe.jkta.usage.Is;
+import org.tomitribe.util.Hex;
+import org.tomitribe.util.IO;
+import org.tomitribe.util.PrintString;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.UncheckedIOException;
+import java.net.URL;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class Asmifier {
+
+    private static final AtomicReference<File> tmpDir = new AtomicReference<File>(null);
+
+    static {
+        try {
+            final File asmifier = File.createTempFile("Asmifier", null);
+            tmpDir.set(asmifier.getParentFile());
+            if (!asmifier.delete()) {
+                asmifier.deleteOnExit();
+            }
+        } catch (final IOException e) {
+            throw new RuntimeException("Asmifier failed to locate a temporary directory");
+        }
+    }
+
+    public static void hex(final ClassLoader classLoader, final String className) throws IOException {
+        final String internalName = className.replace('.', '/') + ".class";
+        final URL resource = classLoader.getResource(internalName);
+
+        if (null == resource) {
+            throw new IOException("Failed to find resource: " + internalName);
+        }
+        System.out.println(className);
+        final InputStream inputStream = resource.openStream();
+        byte[] bytes = IO.readBytes(inputStream);
+        for (final byte b : bytes) {
+            System.out.printf("%-2s %-2s%n", Hex.toString(new byte[]{b}), (char) b);
+        }
+    }
+
+    public static void print(final ClassLoader classLoader, final String className) throws IOException {
+        final String internalName = className.replace('.', '/') + ".class";
+        final URL resource = classLoader.getResource(internalName);
+
+        if (null == resource) {
+            throw new IOException("Failed to find resource: " + internalName);
+        }
+
+        final ClassReader reader = new ClassReader(resource.openStream());
+
+
+        final File file = new File("/tmp/" + className);
+
+        write(reader, file);
+    }
+
+    private static void write(final ClassReader reader, final File file) throws IOException {
+        final OutputStream write = IO.write(file);
+        write(reader, write);
+    }
+
+    public static void write(final ClassReader reader, final OutputStream write) throws IOException {
+        final TraceClassVisitor visitor = new TraceClassVisitor(null, new ASMifier(), new PrintWriter(write));
+        reader.accept(visitor, ClassReader.SKIP_DEBUG);
+        write.close();
+    }
+
+    public static void asmify(final Class clazz, final String suffix) throws IOException {
+        asmify(clazz.getName(), Bytecode.readClassFile(clazz.getClassLoader(), clazz), suffix);
+    }
+
+    public static void asmify(final ClassLoader loader, final String className, final String suffix) throws IOException {
+        asmify(className, Bytecode.readClassFile(loader, className), suffix);
+    }
+
+    public static void asmify(final String className, final byte[] bytes, final String suffix) throws IOException {
+        final ClassReader reader = new ClassReader(bytes);
+        final File file = new File(tmpDir.get(), className + "." + suffix);
+
+        write(reader, file);
+    }
+
+    public static String asmify(final byte[] actualBytes) throws IOException {
+        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        write(new ClassReader(actualBytes), byteArrayOutputStream);
+        return new String(byteArrayOutputStream.toByteArray());
+    }
+
+    public static String asmifyJar(final File jar) throws IOException {
+        final PrintString printString = new PrintString();
+        final InputStream read = IO.read(jar);
+        asmifyJar(read, printString);
+        return printString.toString();
+    }
+
+    private static void asmifyJar(final InputStream inputStream, final PrintStream out) throws IOException {
+        final ZipInputStream zipInputStream = new ZipInputStream(inputStream);
+
+        ZipEntry entry;
+        while ((entry = zipInputStream.getNextEntry()) != null) {
+
+            entryMetadata(entry, out);
+
+            final String path = entry.getName();
+
+            if (path.endsWith(".class")) {
+                asmifyClass(zipInputStream, out);
+            } else if (isZip(path)) {
+                asmifyJar(zipInputStream, out);
+            } else {
+                IO.copy(zipInputStream, out);
+            }
+        }
+    }
+
+    private static void entryMetadata(final ZipEntry entry, final PrintStream out) {
+        out.printf("%n-----------------------------------------------%n");
+        out.printf("name: %s%n", entry.getName());
+        out.printf("----%n");
+    }
+
+    private static void asmifyClass(final InputStream inputStream, final PrintStream out) {
+        try {
+            final byte[] bytes = IO.readBytes(inputStream);
+            final String asmify = Asmifier.asmify(bytes);
+            out.println(asmify);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    private static boolean isZip(final String path) {
+        return Is.Zip.accept(path);
+    }
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Bytecode.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Bytecode.java
new file mode 100644
index 0000000..445d528
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Bytecode.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.tomitribe.util.IO;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class Bytecode {
+
+    private Bytecode() {
+        // no-op
+    }
+
+    public static byte[] readClassFile(final Class clazz) throws IOException {
+        ClassLoader classLoader = clazz.getClassLoader();
+        if (classLoader == null) {
+            classLoader = Thread.currentThread().getContextClassLoader();
+        }
+        return readClassFile(classLoader, clazz);
+    }
+
+    public static byte[] readClassFile(final ClassLoader classLoader, final Class clazz) throws IOException {
+        final String internalName = clazz.getName().replace('.', '/') + ".class";
+        final URL resource = classLoader.getResource(internalName);
+        return IO.readBytes(resource);
+    }
+
+    public static byte[] readClassFile(final ClassLoader classLoader, final String className) throws IOException {
+        final String internalName = className.replace('.', '/') + ".class";
+        final URL resource = classLoader.getResource(internalName);
+        return IO.readBytes(resource);
+    }
+
+    public static void read(final byte[] originalBytes, final ClassVisitor classAdapter) {
+        if (originalBytes == null) throw new IllegalStateException("bytecode array is null");
+        final ClassReader cr = new ClassReader(originalBytes);
+        cr.accept(classAdapter, ClassReader.EXPAND_FRAMES);
+    }
+
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ClassTransformerTest.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ClassTransformerTest.java
new file mode 100644
index 0000000..c0ac8f4
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ClassTransformerTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.tomitribe.jkta.usage.Jar;
+import org.tomitribe.jkta.usage.Package;
+import org.tomitribe.jkta.usage.Usage;
+
+import javax.ejb.EJBException;
+import javax.ejb.EnterpriseBean;
+import javax.ejb.SessionBean;
+import javax.enterprise.context.MockScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.spi.Bean;
+import javax.persistence.Persistence;
+import javax.servlet.http.HttpServlet;
+import javax.ws.rs.Path;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.ref.Reference;
+import java.util.Set;
+
+import static org.apache.tomee.patch.core.Scan.assertUsage;
+import static org.apache.tomee.patch.core.Transform.usage;
+
+public class ClassTransformerTest {
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_Negative() {
+        final Usage<Jar> usage = usage(VisitNegative.class);
+
+        assertUsage(usage);
+    }
+
+    public static class Parent {
+    }
+
+    public static interface Contract {
+    }
+
+    public static class VisitNegative extends Parent implements Serializable, Contract {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_SuperClass() {
+        final Usage<Jar> usage = usage(HasSuper.class);
+
+        assertUsage(usage, Package.JAVAX_SERVLET, Package.JAVAX_SERVLET);
+
+    }
+
+    public static class HasSuper extends HttpServlet implements Serializable, Contract {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_Interfaces() {
+        final Usage<Jar> usage = usage(HasInterface.class);
+
+        assertUsage(usage, Package.JAVAX_EJB);
+
+    }
+
+    public static class HasInterface implements Serializable, EnterpriseBean, Contract {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_Signature() {
+        final Usage<Jar> usage = usage(HasSignature.class);
+
+        assertUsage(usage, Package.JAVAX_EJB);
+
+    }
+
+    public static class HasSignature<T extends SessionBean> {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_Signature2() {
+        final Usage<Jar> usage = usage(HasSignature2.class);
+
+        assertUsage(usage, Package.JAVAX_EJB);
+
+    }
+
+    public static interface HasSignature2 extends Set<SessionBean> {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visit_All() {
+        final Usage<Jar> usage = usage(HasAll.class);
+
+        assertUsage(usage,
+                Package.JAVAX_EJB,
+                Package.JAVAX_SERVLET,
+                Package.JAVAX_SERVLET,
+                Package.JAVAX_PERSISTENCE
+        );
+
+    }
+
+    public static interface Generic<S> {
+    }
+
+    public static class HasAll extends HttpServlet implements Serializable, EnterpriseBean, Generic<Persistence> {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation() {
+        final Usage<Jar> usage = usage(HasAnnotation.class);
+
+        assertUsage(usage, Package.JAVAX_ENTERPRISE);
+    }
+
+    @RequestScoped
+    public static class HasAnnotation {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation_Deep() {
+        final Usage<Jar> usage = usage(HasAnnotationData.class);
+
+        assertUsage(usage, Package.JAVAX_WS_RS, Package.JAVAX_SERVLET);
+    }
+
+    @ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)})
+    public static class HasAnnotationData {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTypeAnnotation() {
+        final Usage<Jar> usage = usage(HasTypeAnnotation.class);
+
+        assertUsage(usage, Package.JAVAX_ENTERPRISE);
+    }
+
+    public static class HasTypeAnnotation implements Generic<@MockScoped Reference> {
+    }
+
+    // ------------------------------------------------------
+
+    @Ignore
+    @Test
+    public void visitTypeAnnotation_Deep_PossibleAsmBug() {
+        final Usage<Jar> usage = usage(HasTypeAnnotationDeep.class);
+
+        assertUsage(usage, Package.JAVAX_WS_RS, Package.JAVAX_SERVLET);
+    }
+
+    public static class HasTypeAnnotationDeep implements Generic<@ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) Reference> {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitField() {
+        final Usage<Jar> usage = usage(new Object() {
+            SessionBean sb;
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitField_Signature1() {
+        final Usage<Jar> usage = usage(new Object() {
+            final Reference<SessionBean> sb = null;
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    /**
+     * The "Bean" type will show up both in ASM's field descriptor
+     * and in the generic signature string.  We should only count
+     * one of them.
+     */
+    @Test
+    public void visitField_SignatureNoDuplicate() {
+        final Usage<Jar> usage = usage(new Object() {
+            Bean<SessionBean> bean;
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB, Package.JAVAX_ENTERPRISE);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethod_Return() {
+        final Usage<Jar> usage = usage(new Object() {
+            public SessionBean get() {
+                return null;
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethod_ReturnGeneric() {
+        final Usage<Jar> usage = usage(new Object() {
+            public Generic<SessionBean> get() {
+                return null;
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethod_Parameter() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void get(SessionBean sb) {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethod_ParameterGeneric() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void get(Object o, Generic<SessionBean> sb, int i) {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethod_Throws() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void get(Serializable s) throws EJBException, IOException {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Data.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Data.java
new file mode 100644
index 0000000..40ba02f
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Data.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import javax.ejb.LockType;
+import javax.ws.rs.Path;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Data {
+    int length() default 2;
+
+    String name() default "";
+
+    LockType lock() default LockType.READ;
+
+    Path path() default @Path("/");
+
+    Class type() default Object.class;
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/FieldTransformerTest.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/FieldTransformerTest.java
new file mode 100644
index 0000000..ebf85ed
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/FieldTransformerTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.tomitribe.jkta.usage.Jar;
+import org.tomitribe.jkta.usage.Package;
+import org.tomitribe.jkta.usage.Usage;
+
+import javax.enterprise.context.MockScoped;
+import javax.persistence.Id;
+import javax.servlet.http.HttpServlet;
+import javax.ws.rs.Path;
+import java.util.Set;
+
+import static org.apache.tomee.patch.core.Scan.assertUsage;
+import static org.apache.tomee.patch.core.Transform.usage;
+
+public class FieldTransformerTest {
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Id
+            private Object o;
+        });
+
+        assertUsage(usage, Package.JAVAX_PERSISTENCE);
+    }
+
+    // ------------------------------------------------------
+
+    @Ignore
+    @Test
+    public void visitAnnotation_Deep_PossibleAsmBug() {
+        final Usage<Jar> usage = usage(new Object() {
+            @ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)})
+            private Object o;
+        });
+
+        assertUsage(usage, Package.JAVAX_SERVLET, Package.JAVAX_WS_RS);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Data(type = HttpServlet.class)
+            private Object o;
+        });
+
+        assertUsage(usage, Package.JAVAX_SERVLET);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTypeAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            Set<@MockScoped Long> set;
+        });
+
+        assertUsage(usage, Package.JAVAX_ENTERPRISE);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTypeAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            Set<@ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) Long> set;
+        });
+
+        assertUsage(usage, Package.JAVAX_SERVLET, Package.JAVAX_WS_RS);
+    }
+
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/MethodTransformerTest.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/MethodTransformerTest.java
new file mode 100644
index 0000000..914d1f7
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/MethodTransformerTest.java
@@ -0,0 +1,445 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.tomitribe.jkta.usage.BytecodeUsage;
+import org.tomitribe.jkta.usage.Jar;
+import org.tomitribe.jkta.usage.MethodScanner;
+import org.tomitribe.jkta.usage.Package;
+import org.tomitribe.jkta.usage.Usage;
+
+import javax.ejb.EnterpriseBean;
+import javax.ejb.Process;
+import javax.ejb.Schedule;
+import javax.ejb.ScheduleExpression;
+import javax.ejb.SessionBean;
+import javax.enterprise.context.MockScoped;
+import javax.jms.EnterpriseBeanConsumer;
+import javax.persistence.EntityBean;
+import javax.persistence.Persist;
+import javax.persistence.PersistenceException;
+import javax.servlet.http.HttpServlet;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Cookie;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.tomee.patch.core.Scan.assertUsage;
+import static org.apache.tomee.patch.core.Transform.usage;
+
+public class MethodTransformerTest {
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            @Schedule
+            public void get() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            @ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)})
+            public void get() {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_SERVLET, Package.JAVAX_WS_RS);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTypeAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            public <@MockScoped V> V get() {
+                return null;
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_ENTERPRISE);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTypeAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            public <@ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) V> V get() {
+                return null;
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_SERVLET, Package.JAVAX_WS_RS);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitParameterAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m(@PathParam("id") int id) {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_WS_RS);
+    }
+
+    // ------------------------------------------------------
+
+    @Ignore
+    @Test
+    public void visitParameterAnnotation_Deep_PotentialAsmBug() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m(@ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) int id) {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_WS_RS, Package.JAVAX_SERVLET);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitParameterAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m(@Data(type = HttpServlet.class) int id) {
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_SERVLET);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitFrame() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m(Object o) {
+                EnterpriseBean bean = (SessionBean) o;
+                try {
+                    m(bean);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTypeInsn() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m(Object o) {
+                final Object bean = (SessionBean) o;
+                System.out.println(bean);
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitFieldInsn() {
+        final Usage<Jar> usage = usage(new Object() {
+            final SessionBean bean = null;
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethodInsn() {
+        final Usage<Jar> usage = usage(new Object() {
+
+            public void m() {
+                new ScheduleExpression();
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_EJB, Package.JAVAX_EJB);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMethodInsn_Descriptor() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m(final EnterpriseBeanConsumer consumer, final EntityBean bean) {
+                consumer.accept(bean);
+            }
+        });
+
+        assertUsage(usage, Package.JAVAX_JMS, Package.JAVAX_JMS, Package.JAVAX_EJB, Package.JAVAX_PERSISTENCE);
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitInvokeDynamicInsn_Direct() {
+        final Usage usage = new Usage();
+        final MethodScanner methodScanner = new MethodScanner(Opcodes.ASM8, new BytecodeUsage(usage, Opcodes.ASM8));
+        methodScanner.visitInvokeDynamicInsn(
+                "accept",
+                "(Ljavax/ejb/Process;)Ljavax/jms/Consumer;",
+                new Handle(Opcodes.H_INVOKESTATIC,
+                        "java/lang/invoke/LambdaMetafactory",
+                        "metafactory",
+                        "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
+                        false),
+                new Object[]{
+                        Type.getType("(Ljava/lang/Object;)V"),
+                        new Handle(Opcodes.H_INVOKEVIRTUAL,
+                                "javax/ejb/Process",
+                                "process",
+                                "(Ljavax/ejb/EnterpriseBean;)V",
+                                false),
+                        Type.getType("(Ljavax/ejb/EnterpriseBean;)V")
+                }
+        );
+
+        assertUsage(usage,
+                Package.JAVAX_EJB,
+                Package.JAVAX_EJB,
+                Package.JAVAX_EJB,
+                Package.JAVAX_EJB,
+                Package.JAVAX_JMS
+        );
+
+    }
+
+    @Test
+    public void visitInvokeDynamicInsn() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void invokedynamic(Persist<EnterpriseBean> persist, Process process) {
+                persist.forEach(process::process);
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_PERSISTENCE, // visitMethod
+                Package.JAVAX_EJB, // visitMethod
+                Package.JAVAX_EJB, // visitMethod
+                Package.JAVAX_EJB, // visitInvokeDynamicInsn
+                Package.JAVAX_EJB, // visitInvokeDynamicInsn
+                Package.JAVAX_EJB, // visitInvokeDynamicInsn
+                Package.JAVAX_EJB, // visitInvokeDynamicInsn
+                Package.JAVAX_JMS, // visitInvokeDynamicInsn
+                Package.JAVAX_PERSISTENCE, // visitMethodInsn
+                Package.JAVAX_JMS // visitMethodInsn
+        );
+
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitLdcInsn_Type() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                System.out.println(GET.class);
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_WS_RS
+        );
+    }
+
+    // ------------------------------------------------------
+
+    /**
+     * TODO This is a stub.  Real test needed.
+     */
+    @Ignore("https://github.com/tomitribe/jkta/issues/2")
+    @Test
+    public void visitLdcInsn_Handle() {
+    }
+
+    // ------------------------------------------------------
+
+
+    /**
+     * TODO This is a stub.  Real test needed.
+     */
+    @Ignore("https://github.com/tomitribe/jkta/issues/3")
+    @Test
+    public void visitLdcInsn_ConstantDynamic() {
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitMultiANewArrayInsn() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                final Cookie[][][] cookies = new Cookie[4][8][16];
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_WS_RS
+        );
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitInsnAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                final List list = (@MockScoped ArrayList) null;
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_ENTERPRISE
+        );
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitInsnAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                final List list = (@ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) ArrayList) null;
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_SERVLET,
+                Package.JAVAX_WS_RS
+        );
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTryCatchBlock() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                try {
+                    System.out.println();
+                } catch (PersistenceException e) {
+                    System.out.println();
+                }
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_PERSISTENCE, // visitTryCatchBlock
+                Package.JAVAX_PERSISTENCE // visitFrame
+        );
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTryCatchAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                try {
+                    System.out.println();
+                } catch (@MockScoped PersistenceException e) {
+                    System.out.println();
+                }
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_ENTERPRISE, // visitTryCatchBlock
+                Package.JAVAX_PERSISTENCE, // visitTryCatchBlock
+                Package.JAVAX_PERSISTENCE // visitFrame
+        );
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitTryCatchAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                try {
+                    System.out.println();
+                } catch (@ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) PersistenceException e) {
+                    System.out.println();
+                }
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_SERVLET,
+                Package.JAVAX_WS_RS,
+                Package.JAVAX_PERSISTENCE,
+                Package.JAVAX_PERSISTENCE
+        );
+    }
+
+    // ------------------------------------------------------
+
+    @Test
+    public void visitLocalVariableAnnotation() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                @MockScoped long e = System.nanoTime();
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_ENTERPRISE
+        );
+    }
+    // ------------------------------------------------------
+
+    @Test
+    public void visitLocalVariableAnnotation_Deep() {
+        final Usage<Jar> usage = usage(new Object() {
+            public void m() {
+                @ArrayData(data = {@Data(path = @Path("/foo")), @Data(type = HttpServlet.class)}) long e = System.nanoTime();
+            }
+        });
+
+        assertUsage(usage,
+                Package.JAVAX_SERVLET,
+                Package.JAVAX_WS_RS
+        );
+    }
+
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ModuleTransformerTest.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ModuleTransformerTest.java
new file mode 100644
index 0000000..6df77e1
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/ModuleTransformerTest.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+public class ModuleTransformerTest {
+
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Scan.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Scan.java
new file mode 100644
index 0000000..db482b2
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Scan.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.tomitribe.jkta.usage.Jar;
+import org.tomitribe.jkta.usage.JarUsage;
+import org.tomitribe.jkta.usage.Package;
+import org.tomitribe.jkta.usage.Usage;
+import org.tomitribe.util.Archive;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+
+import static org.junit.Assert.assertEquals;
+
+public class Scan {
+    private Scan() {
+    }
+
+    public static Usage<Jar> usage(final Object o) {
+        return usage(o.getClass());
+    }
+
+    public static Usage<Jar> usage(final Class<?> aClass) {
+        try {
+//            final ClassLoader loader = aClass.getClassLoader();
+//            System.out.println(Asmifier.asmify(Bytecode.readClassFile(loader, aClass)));
+//            System.out.println();
+            final File jar = Archive.archive().add(aClass).toJar();
+            return JarUsage.of(jar);
+        } catch (IOException | NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void assertUsage(final Usage<Jar> usage, final Package... expectedUses) {
+        int javax = 0;
+        int jakarta = 0;
+        int[] uses = new int[Package.values().length];
+
+        for (final Package use : expectedUses) {
+            uses[use.ordinal()]++;
+            if (use.getName().startsWith("javax.")) javax++;
+            if (use.getName().startsWith("jakarta.")) jakarta++;
+        }
+
+        for (int i = 0; i < uses.length; i++) {
+            final Package pkg = Package.values()[i];
+            assertEquals(pkg.getName(), uses[i], usage.get(pkg));
+        }
+
+        assertEquals(javax, usage.getJavax());
+        assertEquals(jakarta, usage.getJakarta());
+    }
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/SignatureTransformerTest.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/SignatureTransformerTest.java
new file mode 100644
index 0000000..7a62a79
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/SignatureTransformerTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.junit.Test;
+
+public class SignatureTransformerTest {
+
+    @Test
+    public void visitArrayType() {
+    }
+
+    @Test
+    public void visitClassType() {
+    }
+
+    @Test
+    public void visitInnerClassType() {
+    }
+
+    @Test
+    public void visitTypeArgument() {
+    }
+}
diff --git a/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Transform.java b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Transform.java
new file mode 100644
index 0000000..f3fdfa3
--- /dev/null
+++ b/tomee-patch-core/src/test/java/org/apache/tomee/patch/core/Transform.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.core;
+
+import org.junit.Assert;
+import org.tomitribe.jkta.usage.Jar;
+import org.tomitribe.jkta.usage.JarUsage;
+import org.tomitribe.jkta.usage.Usage;
+import org.tomitribe.util.Archive;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.security.NoSuchAlgorithmException;
+import java.util.stream.Stream;
+
+public class Transform {
+    private Transform() {
+    }
+
+    public static Usage<Jar> usage(final Object o) {
+        return usage(o.getClass());
+    }
+
+    public static Usage<Jar> usage(final Class<?> aClass) {
+        try {
+            final File jar = new TestArchive().add(aClass).toJar();
+
+            final Usage<Jar> usageBefore = JarUsage.of(jar);
+
+            final File transformed = Transformation.transform(jar);
+
+            final String contentsBefore = Asmifier.asmifyJar(jar);
+            final String contentsAfter = Asmifier.asmifyJar(transformed);
+
+            Assert.assertEquals(contentsBefore, contentsAfter);
+
+            return JarUsage.of(transformed);
+        } catch (IOException | NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static class TestArchive extends Archive {
+        public Archive add(final Class<?> clazz) {
+            try {
+                final String name = clazz.getName().replace('.', '/') + ".class";
+
+                final URL resource = this.getClass().getClassLoader().getResource(name);
+                if (resource == null) throw new IllegalStateException("Cannot find class file for " + clazz.getName());
+                add(name, resource);
+
+                // Add any anonymous nested classes
+                Stream.of(clazz.getDeclaredClasses())
+                        .filter(Class::isAnonymousClass)
+                        .forEach(this::add);
+
+                return this;
+            } catch (final IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+}
diff --git a/tomee-patch-plugin/pom.xml b/tomee-patch-plugin/pom.xml
index 5ed2fb9..f68116a 100644
--- a/tomee-patch-plugin/pom.xml
+++ b/tomee-patch-plugin/pom.xml
@@ -31,5 +31,93 @@
   <artifactId>tomee-patch-plugin</artifactId>
   <packaging>maven-plugin</packaging>
 
+  <properties>
+    <maven.version>3.2.2</maven.version>
+    <maven-plugin.prefix>transform</maven-plugin.prefix>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <version>3.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>3.0.17</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>${maven.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-model</artifactId>
+      <version>${maven.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+      <version>${maven.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+      <version>1.4</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>${maven.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-compat</artifactId>
+      <version>${maven.version}</version>
+    </dependency>
+
+    <!-- TESTS -->
+    <dependency>
+      <groupId>org.apache.maven.plugin-testing</groupId>
+      <artifactId>maven-plugin-testing-harness</artifactId>
+      <version>3.2.0</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-aether-provider</artifactId>
+      <version>${maven.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.shrinkwrap</groupId>
+      <artifactId>shrinkwrap-api</artifactId>
+      <version>1.2.6</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.shrinkwrap</groupId>
+      <artifactId>shrinkwrap-impl-base</artifactId>
+      <version>1.2.6</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax</groupId>
+      <artifactId>javaee-api</artifactId>
+      <version>8.0.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
 </project>
 
diff --git a/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/TransformMojo.java b/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/TransformMojo.java
new file mode 100644
index 0000000..27c06ad
--- /dev/null
+++ b/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/TransformMojo.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package org.apache.tomee.patch.plugin;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+@Mojo(name = "run", requiresDependencyResolution = ResolutionScope.RUNTIME_PLUS_SYSTEM, defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true)
+public class TransformMojo extends AbstractMojo {
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+
+    }
+}


[tomee-patch-plugin] 01/02: Initial plugin layout

Posted by db...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-patch-plugin.git

commit 9a4b40ee29de46d0f1b48e7352cf9a570fb840da
Author: David Blevins <da...@gmail.com>
AuthorDate: Wed Jun 10 18:12:53 2020 -0700

    Initial plugin layout
---
 .gitignore                 | 23 ++++++++++++
 pom.xml                    | 88 ++++++++++++++++++++++++++++++++++++++++++++++
 tomee-patch-core/pom.xml   | 34 ++++++++++++++++++
 tomee-patch-plugin/pom.xml | 35 ++++++++++++++++++
 4 files changed, 180 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..da38c0a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+target
+.classpath
+.project
+.settings
+.idea
+*.ipr
+*.iml
+*.log
+*.vscode
+*~
+quick.bat
+/tomee/tomee-plume-webapp/overlays/
+/tomee/tomee-plus-webapp/overlays/
+/temp
+/report.txt
+nb-configuration.xml
+.factorypath
+.history
+**/test/key
+tck/**/temp
+examples/jaxrs-json-provider-jettison/temp/
+transformer/jakartaee-prototype/
+transformer/transformer-0.1.0-SNAPSHOT/
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..de443de
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>21</version>
+    <relativePath><!--Resolve on repository--></relativePath>
+  </parent>
+
+
+  <groupId>org.apache.tomee.patch</groupId>
+  <artifactId>tomee-patch-parent</artifactId>
+  <packaging>pom</packaging>
+  <version>0.1-SNAPSHOT</version>
+
+  <name>Apache TomEE Patch Plugin</name>
+  <description>Tools and Maven Plugin to help complete the javax-to-jakarta bytecode transformation</description>
+  <url>http://tomee.apache.org</url>
+  <inceptionYear>1999</inceptionYear>
+
+  <prerequisites>
+    <maven>3.2.5</maven>
+  </prerequisites>
+
+  <scm>
+    <connection>scm:git:git@github.com:apache/tomee-patch-plugin.git</connection>
+    <url>scm:git:git@github.com:apache/tomee-patch-plugin.git</url>
+    <developerConnection>scm:git:git@github.com:apache/tomee-patch-plugin.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <issueManagement>
+    <system>jira</system>
+    <url>http://issues.apache.org/jira/browse/TOMEE</url>
+  </issueManagement>
+
+  <mailingLists>
+    <mailingList>
+      <name>TomEE Commits List</name>
+      <subscribe>commits-subscribe@tomee.apache.org</subscribe>
+      <unsubscribe>commits-unsubscribe@tomee.apache.org</unsubscribe>
+      <post>commits@tomee.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/tomee-commits/</archive>
+    </mailingList>
+    <mailingList>
+      <name>TomEE Developer List</name>
+      <subscribe>dev-subscribe@tomee.apache.org</subscribe>
+      <unsubscribe>dev-unsubscribe@tomee.apache.org</unsubscribe>
+      <post>dev@tomee.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/tomee-dev/</archive>
+    </mailingList>
+    <mailingList>
+      <name>TomEE Users List</name>
+      <subscribe>users-subscribe@tomee.apache.org</subscribe>
+      <unsubscribe>users-unsubscribe@tomee.apache.org</unsubscribe>
+      <post>users@tomee.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/tomee-users/</archive>
+    </mailingList>
+  </mailingLists>
+
+  <modules>
+    <module>tomee-patch-core</module>
+    <module>tomee-patch-plugin</module>
+  </modules>
+</project>
+
diff --git a/tomee-patch-core/pom.xml b/tomee-patch-core/pom.xml
new file mode 100644
index 0000000..93e381c
--- /dev/null
+++ b/tomee-patch-core/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.tomee.patch</groupId>
+    <artifactId>tomee-patch-parent</artifactId>
+    <version>0.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>tomee-patch-core</artifactId>
+  
+</project>
+
diff --git a/tomee-patch-plugin/pom.xml b/tomee-patch-plugin/pom.xml
new file mode 100644
index 0000000..5ed2fb9
--- /dev/null
+++ b/tomee-patch-plugin/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.tomee.patch</groupId>
+    <artifactId>tomee-patch-parent</artifactId>
+    <version>0.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>tomee-patch-plugin</artifactId>
+  <packaging>maven-plugin</packaging>
+
+</project>
+