Skip to content

Commit

Permalink
Merge pull request wildfly#17119 from kabir/WFLY-18370-sar-tccl-problem
Browse files Browse the repository at this point in the history
[WFLY-18370] Remove the workaround sar dependency, and add test
  • Loading branch information
bstansberry authored Sep 21, 2023
2 parents 66f2144 + f311c4c commit 1685d74
Show file tree
Hide file tree
Showing 14 changed files with 336 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,5 @@
<module name="org.jboss.metadata.common"/>
<module name="org.jboss.as.naming"/>
<module name="java.xml"/>
<!--
The Angus Activation services are required to register a Web Service via a management Bean
-->
<module name="org.eclipse.angus.activation" services="import" optional="true"/>
</dependencies>
</module>
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);
}
}
}

}
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();
}
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();
}
}
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>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.test.integration.sar.context.classloader;
package org.jboss.as.test.integration.sar.context.classloader.module;

/**
* @author: Jaikiran Pai
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.test.integration.sar.context.classloader;
package org.jboss.as.test.integration.sar.context.classloader.module;

/**
* @author: Jaikiran Pai
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.test.integration.sar.context.classloader;
package org.jboss.as.test.integration.sar.context.classloader.module;

/**
* @author: Jaikiran Pai
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.test.integration.sar.context.classloader;
package org.jboss.as.test.integration.sar.context.classloader.module;

/**
* @author: Jaikiran Pai
Expand Down
Loading

0 comments on commit 1685d74

Please sign in to comment.