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 #1326
  • Loading branch information
ppalaga committed Apr 10, 2024
1 parent 5fe8b65 commit d9a7770
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 15 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 static class HelloServiceStringImpl implements HelloServiceString {

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

}

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

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

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import jakarta.ws.rs.core.Response;

import io.quarkiverse.cxf.annotation.CXFClient;
import io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageServiceWithWrappers;

@Path("/mtom-awt-rest")
@ApplicationScoped
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkiverse.cxf.it.ws.mtom.awt.server;
package io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers;

import java.awt.Image;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkiverse.cxf.it.ws.mtom.awt.server;
package io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers;

import java.awt.Image;

Expand Down Expand Up @@ -33,4 +33,4 @@ public Image getReturn() {
public void setReturn(Image data) {
this._return = data;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkiverse.cxf.it.ws.mtom.awt.server;
package io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers;

import java.awt.Image;

Expand All @@ -16,12 +16,12 @@ public interface ImageServiceWithWrappers {
public static final String NS = "https://quarkiverse.github.io/quarkiverse-docs/quarkus-cxf/test/mtom-awt-with-wrappers";

@WebMethod
@ResponseWrapper(localName = "ImageResponse", targetNamespace = NS, className = "io.quarkiverse.cxf.it.ws.mtom.awt.server.ImageResponse")
@ResponseWrapper(localName = "ImageResponse", targetNamespace = NS, className = "io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageResponse")
Image downloadImage(
@WebParam(name = "name", targetNamespace = NS) String name);

@WebMethod
@RequestWrapper(localName = "ImageData", targetNamespace = NS, className = "io.quarkiverse.cxf.it.ws.mtom.awt.server.ImageData")
@RequestWrapper(localName = "ImageData", targetNamespace = NS, className = "io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageData")
String uploadImage(
@WebParam(name = "data", targetNamespace = NS) Image data,
@WebParam(name = "name", targetNamespace = NS) String name);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.quarkiverse.cxf.it.ws.mtom.awt.server;
package io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers;

import java.awt.Image;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import jakarta.jws.WebService;

@WebService(name = "ImageServiceWithWrappers", serviceName = "ImageServiceWithWrappers", endpointInterface = "io.quarkiverse.cxf.it.ws.mtom.awt.server.ImageServiceWithWrappers", targetNamespace = ImageServiceWithWrappers.NS)
@WebService(name = "ImageServiceWithWrappers", serviceName = "ImageServiceWithWrappers", endpointInterface = "io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageServiceWithWrappers", targetNamespace = ImageServiceWithWrappers.NS)
public class ImageServiceWithWrappersImpl implements ImageServiceWithWrappers {

public static final String MSG_SUCCESS = "Upload Successful";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ quarkus.cxf.client.imageServiceClient.endpoint-namespace = "https://quarkiverse.
quarkus.cxf.client.imageServiceClient.endpoint-name = ImageService
quarkus.cxf.client.imageServiceClient.native.runtime-initialized = true

quarkus.cxf.endpoint."/mtom-aws-with-wrappers".implementor = io.quarkiverse.cxf.it.ws.mtom.awt.server.ImageServiceWithWrappersImpl
quarkus.cxf.endpoint."/mtom-aws-with-wrappers".implementor = io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageServiceWithWrappersImpl
quarkus.cxf.endpoint."/mtom-aws-with-wrappers".features = org.apache.cxf.ext.logging.LoggingFeature
quarkus.cxf.endpoint."/mtom-aws-with-wrappers".handlers = io.quarkiverse.cxf.it.ws.mtom.awt.server.MtomEnforcer

quarkus.cxf.client.imageServiceClientWithWrappers.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/mtom-aws-with-wrappers/ImageServiceWithWrappers
quarkus.cxf.client.imageServiceClientWithWrappers.service-interface = io.quarkiverse.cxf.it.ws.mtom.awt.server.ImageServiceWithWrappers
quarkus.cxf.client.imageServiceClientWithWrappers.service-interface = io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageServiceWithWrappers
quarkus.cxf.client.imageServiceClientWithWrappers.endpoint-namespace = "https://quarkiverse.github.io/quarkiverse-docs/quarkus-cxf/test/mtom-awt-with-wrappers"
quarkus.cxf.client.imageServiceClientWithWrappers.endpoint-name = ImageServiceWithWrappers
quarkus.cxf.client.imageServiceClientWithWrappers.native.runtime-initialized = true
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.junit.jupiter.api.Test;

import io.quarkiverse.cxf.it.ws.mtom.awt.server.MtomAwtResource.ClientKey;
import io.quarkiverse.cxf.it.ws.mtom.awt.server.wrappers.ImageServiceWithWrappersImpl;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
Expand Down

0 comments on commit d9a7770

Please sign in to comment.