Skip to content

Commit

Permalink
Make the class generation fail at build time when there are two
Browse files Browse the repository at this point in the history
same-name sevice methods in the same Java package quarkiverse#1326
  • Loading branch information
ppalaga committed Apr 10, 2024
1 parent 39a9247 commit c6cffa7
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Random;
Expand Down Expand Up @@ -659,7 +661,7 @@ public InputSource resolveEntity(String publicId, String systemId) {
private static class QuarkusCapture implements GeneratedClassClassLoaderCapture {
private final ClassOutput classOutput;

private final Set<String> generatedClasses = new LinkedHashSet<>();
private final Map<String, byte[]> generatedClasses = new LinkedHashMap<>();

QuarkusCapture(ClassOutput classOutput) {
this.classOutput = classOutput;
Expand All @@ -668,12 +670,16 @@ private static class QuarkusCapture implements GeneratedClassClassLoaderCapture
@Override
public void capture(String name, byte[] bytes) {
final String dotName = name.indexOf('.') >= 0 ? name : name.replace('/', '.');
if (!generatedClasses.contains(dotName)) {
final String slashName = name.indexOf('/') >= 0 ? name : name.replace('.', '/');
final String slashName = name.indexOf('/') >= 0 ? name : name.replace('.', '/');
final byte[] oldVal = generatedClasses.get(dotName);
if (oldVal != null && !Arrays.equals(oldVal, bytes)) {
throw new IllegalStateException("Cannot overwrite an existing generated class file " + slashName
+ " with a different content. Is there perhaps a naming clash among the methods of your service interfaces?");
} else {
classOutput.getSourceWriter(slashName);
LOGGER.debugf("Generated class %s", dotName);
classOutput.write(slashName, bytes);
generatedClasses.add(dotName);
generatedClasses.put(dotName, bytes);
}
}

Expand All @@ -682,7 +688,7 @@ public int getGeneratedClassesCount() {
}

public String[] getGeneratedClasses() {
return generatedClasses.toArray(new String[0]);
return generatedClasses.keySet().toArray(new String[0]);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.quarkiverse.cxf.deployment.test;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;

import jakarta.jws.WebMethod;
import jakarta.jws.WebService;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkiverse.cxf.annotation.CXFClient;
import io.quarkus.test.QuarkusUnitTest;

/**
* A reproducer for https://github.com/quarkiverse/quarkus-cxf/issues/1326
*/
public class AsmNamingClashTest {

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.withApplicationRoot(root -> root.addClasses(HelloServiceString.class, HelloServiceStringImpl.class))
.overrideConfigKey("quarkus.cxf.endpoint.\"/helloString\".implementor", HelloServiceStringImpl.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloString.service-interface", HelloServiceString.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloString.client-endpoint-url",
"http://localhost:8081/services/helloString")
.overrideConfigKey("quarkus.cxf.endpoint.\"/helloInt\".implementor", HelloServiceIntImpl.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloInt.service-interface", HelloServiceInt.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloInt.client-endpoint-url", "http://localhost:8081/services/helloInt")
.assertException(t -> Assertions.assertThat(t).isInstanceOf(IllegalStateException.class)
.hasMessageContaining(
"Cannot overwrite an existing generated class file io/quarkiverse/cxf/deployment/test/jaxws_asm/Hello with a different content"));

@CXFClient("helloString")
HelloServiceString helloString;

@CXFClient("helloInt")
HelloServiceInt helloInt;

@Test
void payloadLogged() throws IOException {

Assertions.assertThat(helloString.hello("Joe")).isEqualTo("Hello Joe!");
Assertions.assertThat(helloInt.hello(42)).isEqualTo("Hello 42!");

}

@WebService(targetNamespace = "http://deployment.logging.features.cxf.quarkiverse.io/")
public interface HelloServiceString {

@WebMethod
String hello(String text);

}

@WebService(targetNamespace = "http://deployment.logging.features.cxf.quarkiverse.io/")
public interface HelloServiceInt {

@WebMethod
String hello(int i);

}

@WebService(serviceName = "HelloService")
public class HelloServiceStringImpl implements HelloServiceString {

@WebMethod
@Override
public String hello(String text) {
return "Hello " + text + "!";
}

}

@WebService(serviceName = "HelloService")
public class HelloServiceIntImpl implements HelloServiceInt {

@WebMethod
@Override
public String hello(int text) {
return "Hello " + text + "!";
}

}
}

0 comments on commit c6cffa7

Please sign in to comment.