diff --git a/appserver/ejb/ejb-container/pom.xml b/appserver/ejb/ejb-container/pom.xml index bc4aa65fc25..8f01a0665fb 100755 --- a/appserver/ejb/ejb-container/pom.xml +++ b/appserver/ejb/ejb-container/pom.xml @@ -222,6 +222,18 @@ org.hamcrest hamcrest + + org.openjdk.jmh + jmh-core + 1.32 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.32 + test + diff --git a/appserver/ejb/ejb-container/src/test/java/com/sun/ejb/EJBUtilsTest.java b/appserver/ejb/ejb-container/src/test/java/com/sun/ejb/EJBUtilsTest.java new file mode 100644 index 00000000000..e5e10707925 --- /dev/null +++ b/appserver/ejb/ejb-container/src/test/java/com/sun/ejb/EJBUtilsTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2021 Eclipse Foundation and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package com.sun.ejb; + +import com.sun.ejb.codegen.ClassGeneratorFactory; +import com.sun.ejb.codegen.Generator; +import com.sun.ejb.codegen.ServiceInterfaceGenerator; + +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +import org.glassfish.pfl.dynamic.codegen.spi.Wrapper; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.results.Result; +import org.openjdk.jmh.results.RunResult; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +import static java.lang.reflect.Modifier.PUBLIC; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.lessThan; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author David Matejcek + */ +public class EJBUtilsTest { + + private static final ClassLoader loader = EJBUtilsTest.class.getClassLoader(); + + @Test + public void generateSEI_Benchmark() throws Exception { + Options options = new OptionsBuilder() + .include(getClass().getName() + ".*") + .mode(Mode.AverageTime) + .warmupIterations(0) + .measurementIterations(2) + .measurementTime(TimeValue.seconds(1L)) + .forks(1) + .threads(20) + .shouldFailOnError(true) + .shouldDoGC(true) + .timeout(TimeValue.seconds(5L)) + .timeUnit(TimeUnit.NANOSECONDS) + .build(); + + Collection results = new Runner(options).run(); + assertThat(results, hasSize(1)); + Result result = results.iterator().next().getAggregatedResult().getPrimaryResult(); + assertThat(result.getScore(), lessThan(100000d)); + } + + + @Benchmark + public void generateSei_Benchmark() throws Exception { + ClassGeneratorFactory generator = new CustomGenerator(); + Class newClass = EJBUtils.generateSEI(generator, generator.className(), loader, EJbUtilsEjbTestClass.class); + assertNotNull(newClass); + assertEquals(generator.className(), newClass.getName()); + } + + + @Test + public void generateSEI_callTwiceWithWrongParameters() throws Exception { + // FIXME: Class will be generated, but with different name -> consecutive call cannot find + // it and cannot generate it again. + EJBUtils.generateSEI(new CustomGenerator(), "com.acme.Fake", loader, EJbUtilsEjbTestClass.class); + EJBUtils.generateSEI(new CustomGenerator(), "com.acme.Fake", loader, EJbUtilsEjbTestClass.class); + } + + + @Test + public void generateSei_ServiceInterfaceGenerator() throws Exception { + ServiceInterfaceGenerator generator = new ServiceInterfaceGenerator(loader, EJbUtilsEjbTestClass.class); + // FIXME: com.sun.ejb.EJBUtilsTest$EJbUtilsEjbTestClass doesn't have expected package com.sun.ejb.internal.jaxws + Class newClass = EJBUtils.generateSEI(generator, generator.getGeneratedClass(), loader, EJbUtilsEjbTestClass.class); + assertNotNull(newClass); + assertEquals(generator.className(), newClass.getName()); + } + + + @Test + public void loadGeneratedRemoteBusinessClasses() throws Exception { + EJBUtils.loadGeneratedRemoteBusinessClasses(EjbUtilsTestInterface.class.getName()); + Class ifaceRemote = loader.loadClass("com.sun.ejb._EJBUtilsTest$EjbUtilsTestInterface_Remote"); + assertTrue(ifaceRemote.isInterface()); + Class iface30 = loader.loadClass("com.sun.ejb.EJBUtilsTest$EjbUtilsTestInterface"); + assertTrue(iface30.isInterface()); + assertDoesNotThrow(() -> EJBUtils.loadGeneratedRemoteBusinessClasses(EjbUtilsTestInterface.class.getName())); + } + + + @Test + public void loadGeneratedGenericEJBHomeClass() throws Exception { + // FIXME: Uses EjbUtils as an anchor, but it is in different package - breaks JDK rules + // com.sun.ejb.codegen vs. com.sun.ejb.EjbUtils + Class newClass = EJBUtils.loadGeneratedGenericEJBHomeClass(loader); + assertNotNull(newClass); + assertTrue(newClass.isInterface()); + assertEquals("com.sun.ejb.codegen.GenericEJBHome_Generated", newClass.getName()); + } + + private static class CustomGenerator extends Generator implements ClassGeneratorFactory { + + @Override + public String getGeneratedClass() { + return "com.sun.ejb.EJBUtilsTestImplFromCustomGenerator"; + } + + @Override + public String className() { + return getGeneratedClass(); + } + + @Override + public void evaluate() { + Wrapper._clear(); + Wrapper._package(getPackageName(className())); + Wrapper._interface(PUBLIC, getBaseName(className())); + Wrapper._classGenerator(); + } + } + + + interface EjbUtilsTestInterface { + void doSomething(); + } + + + public static class EJbUtilsEjbTestClass { + + } +}