forked from wildfly/wildfly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WFLY-18370] Test the application classloader is used for the sar lif…
…ecycle methods Also, double-check this is the case when accessing attributes and invoking methods.
- Loading branch information
Showing
4 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
.../as/test/integration/sar/context/classloader/app/MBeanAppClassLoaderTCCLCheckService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* Copyright 2023, Red Hat, Inc., and individual contributors | ||
* as indicated by the @author tags. See the copyright.txt file in the | ||
* distribution for a full listing of individual contributors. | ||
* | ||
* This is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation; either version 2.1 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* This software is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this software; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
*/ | ||
package org.jboss.as.test.integration.sar.context.classloader.app; | ||
|
||
import java.io.BufferedOutputStream; | ||
import java.io.FileOutputStream; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.StandardOpenOption; | ||
import java.security.AccessController; | ||
import java.security.PrivilegedExceptionAction; | ||
import java.util.Properties; | ||
|
||
public class MBeanAppClassLoaderTCCLCheckService implements MBeanAppClassLoaderTCCLCheckServiceMBean { | ||
|
||
public static final String APP_CL = "application-loader"; | ||
public static final String CONSTRUCTOR_TCCL = "constructor-tccl"; | ||
public static final String ATTR_WRITE_TCCL = "attr-write-tccl"; | ||
public static final String ATTR_READ_TCCL = "attr-read-tccl"; | ||
public static final String INVOKE_TCCL = "invoke-tccl"; | ||
public static final String CREATE_TCCL = "create-tccl"; | ||
public static final String START_TCCL = "start-tccl"; | ||
public static final String STOP_TCCL = "stop-tccl"; | ||
public static final String DESTROY_TCCL = "destroy-tccl"; | ||
|
||
private final Properties properties = new Properties(); | ||
private volatile Path file; | ||
|
||
public MBeanAppClassLoaderTCCLCheckService() { | ||
properties.put(APP_CL, String.valueOf(System.identityHashCode(this.getClass().getClassLoader()))); | ||
storeTccl(CONSTRUCTOR_TCCL); | ||
} | ||
|
||
@Override | ||
public void create() throws Exception { | ||
storeTccl(CREATE_TCCL); | ||
} | ||
|
||
@Override | ||
public void start() throws Exception { | ||
storeTccl(START_TCCL); | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
storeTccl(STOP_TCCL); | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
storeTccl(DESTROY_TCCL); | ||
} | ||
|
||
@Override | ||
public void setFile(String path) throws Exception { | ||
System.out.println("setFile " + path); | ||
storeTccl(ATTR_WRITE_TCCL); | ||
if (file == null) { | ||
file = Path.of(path); | ||
properties.store(new BufferedOutputStream(new FileOutputStream(file.toFile())), "Test"); | ||
} else { | ||
throw new IllegalStateException("Only called once"); | ||
} | ||
} | ||
|
||
@Override | ||
public String getFile() { | ||
storeTccl(ATTR_READ_TCCL); | ||
return null; | ||
} | ||
|
||
@Override | ||
public void method() { | ||
storeTccl(INVOKE_TCCL); | ||
} | ||
|
||
private void storeTccl(String id) { | ||
System.out.println("storeTccl " + id); | ||
ClassLoader cl = Thread.currentThread().getContextClassLoader(); | ||
String clId = String.valueOf(System.identityHashCode(cl)); | ||
if (file == null) { | ||
properties.put(id, clId); | ||
} else { | ||
try { | ||
String s = id + "=" + clId + "\n"; | ||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> { | ||
Files.write(file, s.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); | ||
return null; | ||
}); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} | ||
|
||
} |
34 changes: 34 additions & 0 deletions
34
...est/integration/sar/context/classloader/app/MBeanAppClassLoaderTCCLCheckServiceMBean.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* Copyright 2023, Red Hat, Inc., and individual contributors | ||
* as indicated by the @author tags. See the copyright.txt file in the | ||
* distribution for a full listing of individual contributors. | ||
* | ||
* This is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation; either version 2.1 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* This software is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this software; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
*/package org.jboss.as.test.integration.sar.context.classloader.app; | ||
|
||
public interface MBeanAppClassLoaderTCCLCheckServiceMBean { | ||
// Service lifecycle methods | ||
void create() throws Exception; | ||
void start() throws Exception; | ||
void stop(); | ||
void destroy(); | ||
// Attribute | ||
void setFile(String path) throws Exception; | ||
String getFile(); | ||
// A method | ||
void method(); | ||
} |
142 changes: 142 additions & 0 deletions
142
...boss/as/test/integration/sar/context/classloader/app/MBeanAppClassLoaderTCCLTestCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* Copyright 2023, Red Hat, Inc., and individual contributors | ||
* as indicated by the @author tags. See the copyright.txt file in the | ||
* distribution for a full listing of individual contributors. | ||
* | ||
* This is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation; either version 2.1 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* This software is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this software; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
*/ | ||
package org.jboss.as.test.integration.sar.context.classloader.app; | ||
|
||
import org.jboss.arquillian.container.test.api.Deployment; | ||
import org.jboss.arquillian.container.test.api.RunAsClient; | ||
import org.jboss.arquillian.junit.Arquillian; | ||
import org.jboss.as.arquillian.api.ContainerResource; | ||
import org.jboss.as.arquillian.container.ManagementClient; | ||
import org.jboss.as.controller.PathAddress; | ||
import org.jboss.as.controller.operations.common.Util; | ||
import org.jboss.as.test.integration.common.DefaultConfiguration; | ||
import org.jboss.dmr.ModelNode; | ||
import org.jboss.shrinkwrap.api.Archive; | ||
import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
import org.jboss.shrinkwrap.api.spec.JavaArchive; | ||
import org.junit.After; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.xnio.IoUtils; | ||
|
||
import javax.management.Attribute; | ||
import javax.management.MBeanServerConnection; | ||
import javax.management.ObjectName; | ||
import javax.management.remote.JMXConnector; | ||
import javax.management.remote.JMXConnectorFactory; | ||
import java.io.BufferedReader; | ||
import java.io.FilePermission; | ||
import java.io.FileReader; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.Properties; | ||
|
||
import static org.jboss.as.test.shared.PermissionUtils.createPermissionsXmlAsset; | ||
|
||
@RunWith(Arquillian.class) | ||
@RunAsClient | ||
public class MBeanAppClassLoaderTCCLTestCase { | ||
|
||
@ContainerResource | ||
private ManagementClient managementClient; | ||
|
||
private JMXConnector connector; | ||
|
||
private static final String SAR_NAME = "test-app-tccl.sar"; | ||
|
||
static Path outputPath = Path.of("target/app-cl" + System.currentTimeMillis() + "/tccl.properties"); | ||
|
||
@Deployment | ||
public static Archive createDeployment() { | ||
final JavaArchive sar = ShrinkWrap.create(JavaArchive.class, SAR_NAME); | ||
// add the jboss-service.xml to the META-INF of the .sar | ||
sar.addAsManifestResource(MBeanAppClassLoaderTCCLCheckService.class.getPackage(), "tccl-app-test-service.xml", "jboss-service.xml"); | ||
// add some (dummy) classes to the .sar. These classes will then be attempted to be loaded from the MBean class (which resides in a module) | ||
sar.addClasses(MBeanAppClassLoaderTCCLCheckService.class, MBeanAppClassLoaderTCCLCheckServiceMBean.class); | ||
sar.addAsManifestResource(createPermissionsXmlAsset( | ||
new FilePermission(outputPath.toAbsolutePath().toString(), "read"), | ||
new FilePermission(outputPath.toAbsolutePath().toString(), "write") | ||
), "permissions.xml"); | ||
|
||
return sar; | ||
} | ||
|
||
@After | ||
public void closeConnector() { | ||
IoUtils.safeClose(connector); | ||
} | ||
|
||
/** | ||
* Tests the MBean was deployed successfully and can be invoked. The fact that the MBean deployed successfully is a sign that the TCCL access from within the MBean code, worked fine | ||
* | ||
* @throws Exception | ||
*/ | ||
@Test | ||
public void testTCCLInMBeanInvocation() throws Exception { | ||
final MBeanServerConnection mBeanServerConnection = this.getMBeanServerConnection(); | ||
final ObjectName mbeanObjectName = new ObjectName("wildfly:name=tccl-app-test-mbean"); | ||
|
||
//Path tmp = Path.of("target/app-cl" + System.currentTimeMillis() + "/tccl.properties"); | ||
try { | ||
Files.createDirectories(outputPath.getParent()); | ||
Files.createFile(outputPath); | ||
mBeanServerConnection.setAttribute(mbeanObjectName, new Attribute("File", outputPath.toAbsolutePath().toString())); | ||
mBeanServerConnection.getAttribute(mbeanObjectName, "File"); | ||
mBeanServerConnection.invoke(mbeanObjectName, "method", new Object[0], new String[0]); | ||
|
||
// Undeploy so that the stop and destroy methods get called | ||
ModelNode removeOp = Util.createRemoveOperation(PathAddress.pathAddress("deployment", SAR_NAME)); | ||
managementClient.getControllerClient().execute(removeOp); | ||
|
||
Properties props = new Properties(); | ||
props.load(new BufferedReader(new FileReader(outputPath.toFile()))); | ||
String appCl = props.getProperty(MBeanAppClassLoaderTCCLCheckService.APP_CL); | ||
Assert.assertNotNull(MBeanAppClassLoaderTCCLCheckService.APP_CL, appCl); | ||
|
||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.CONSTRUCTOR_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.CREATE_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.START_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.ATTR_WRITE_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.ATTR_READ_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.INVOKE_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.STOP_TCCL, appCl); | ||
checkProperty(props, MBeanAppClassLoaderTCCLCheckService.DESTROY_TCCL, appCl); | ||
|
||
} finally { | ||
Files.delete(outputPath); | ||
Files.delete(outputPath.getParent()); | ||
} | ||
} | ||
|
||
private void checkProperty(Properties props, String key, String expected) { | ||
Object value = props.get(key); | ||
Assert.assertNotNull(key, value); | ||
Assert.assertEquals(key, expected, value); | ||
} | ||
|
||
private MBeanServerConnection getMBeanServerConnection() throws IOException { | ||
connector = JMXConnectorFactory.connect(managementClient.getRemoteJMXURL(), DefaultConfiguration.credentials()); | ||
return connector.getMBeanServerConnection(); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
.../java/org/jboss/as/test/integration/sar/context/classloader/app/tccl-app-test-service.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!-- | ||
~ JBoss, Home of Professional Open Source. | ||
~ Copyright 2023, Red Hat, Inc., and individual contributors | ||
~ as indicated by the @author tags. See the copyright.txt file in the | ||
~ distribution for a full listing of individual contributors. | ||
~ | ||
~ This is free software; you can redistribute it and/or modify it | ||
~ under the terms of the GNU Lesser General Public License as | ||
~ published by the Free Software Foundation; either version 2.1 of | ||
~ the License, or (at your option) any later version. | ||
~ | ||
~ This software is distributed in the hope that it will be useful, | ||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
~ Lesser General Public License for more details. | ||
~ | ||
~ You should have received a copy of the GNU Lesser General Public | ||
~ License along with this software; if not, write to the Free | ||
~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
~ 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
--> | ||
<server xmlns="urn:jboss:service:7.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="urn:jboss:service:7.0 jboss-service_7_0.xsd"> | ||
|
||
<mbean name="wildfly:name=tccl-app-test-mbean" code="org.jboss.as.test.integration.sar.context.classloader.app.MBeanAppClassLoaderTCCLCheckService"> | ||
</mbean> | ||
</server> |