Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.core.Ordered;

import java.util.Map;
Expand Down Expand Up @@ -113,6 +114,12 @@ public final void onApplicationEvent(ApplicationPreparedEvent event) {

markProcessed(contextId);

context.addApplicationListener(event -> {
if (event instanceof ContextClosedEvent && context == ((ContextClosedEvent) event).getApplicationContext()) {
processedContextIds.remove(contextId);
}
});

onApplicationEvent(springApplication, args, context);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public void setProperty(ConfigurationProperty property, Object newValue) {
Object oldValue = getPropertyValue(propertyName);
if (!Objects.deepEquals(oldValue, convertedNewValue)) {
initializedBeanWrapper.setPropertyValue(propertyName, convertedNewValue);
publishEvent(property, propertyName, oldValue, newValue);
publishEvent(property, propertyName, oldValue, convertedNewValue);
}
}

Expand Down Expand Up @@ -250,9 +250,12 @@ private void initBinding(Class<?> beanClass, String prefix, Map<String, String>
* @return the converted value, or the original value if conversion is not supported
*/
Object convertForProperty(String propertyName, Object value) {
if (value == null) {
return null;
}
Class<?> propertyType = this.initializedBeanWrapper.getPropertyType(propertyName);
ConversionService conversionService = this.initializedBeanWrapper.getConversionService();
if (conversionService.canConvert(value.getClass(), propertyType)) {
if (conversionService != null && conversionService.canConvert(value.getClass(), propertyType)) {
return conversionService.convert(value, propertyType);
}
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ public Object onCreate(ConfigurationPropertyName name, Bindable<?> target, BindC
@Override
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Exception error) throws Exception {
try {
return super.onFailure(name, target, context, error);
Object result = super.onFailure(name, target, context, error);
bindHandlers.onFailure(name, target, context, error);
return result;
} catch (Exception e) {
bindHandlers.onFailure(name, target, context, error);
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ResourceLoader;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -20,7 +21,6 @@
import static io.microsphere.annotation.ConfigurationProperty.APPLICATION_SOURCE;
import static io.microsphere.collection.CollectionUtils.size;
import static io.microsphere.collection.MapUtils.newLinkedHashMap;
import static io.microsphere.collection.SetUtils.newLinkedHashSet;
import static io.microsphere.constants.SeparatorConstants.LINE_SEPARATOR;
import static io.microsphere.logging.LoggerFactory.getLogger;
import static io.microsphere.spring.boot.constants.PropertyConstants.MICROSPHERE_SPRING_BOOT_PROPERTY_NAME_PREFIX;
Expand Down Expand Up @@ -130,12 +130,14 @@ protected Set<String> diagnose(ClassLoader classLoader) {
ArtifactDetector detector = new ArtifactDetector(classLoader);
List<Artifact> artifacts = detector.detect(false);
// Artifacts conflict Map
Map<String, Artifact> artifactsCollisionMap = getArtifactsCollisionMap(artifacts);
Map<String, List<Artifact>> artifactsCollisionMap = getArtifactsCollisionMap(artifacts);
if (!artifactsCollisionMap.isEmpty()) {
StringJoiner stringJoiner = new StringJoiner(LINE_SEPARATOR, "-\t", "");
logger.error("Artifacts collision detected:");
for (Artifact artifact : artifactsCollisionMap.values()) {
stringJoiner.add(artifact.toString());
for (List<Artifact> collidingArtifacts : artifactsCollisionMap.values()) {
for (Artifact artifact : collidingArtifacts) {
stringJoiner.add(artifact.toString());
}
}
logger.error(stringJoiner.toString());
}
Expand All @@ -145,27 +147,33 @@ protected Set<String> diagnose(ClassLoader classLoader) {
/**
* Build a map of colliding artifacts from the given list. An artifact is considered colliding
* if another artifact with the same identifier (groupId:artifactId) already exists in the list.
* All occurrences of a collision (both first and subsequent duplicates) are tracked.
*
* <h3>Example Usage</h3>
* <pre>{@code
* ArtifactDetector detector = new ArtifactDetector(classLoader);
* List<Artifact> artifacts = detector.detect(false);
* Map<String, Artifact> collisionMap = listener.getArtifactsCollisionMap(artifacts);
* collisionMap.forEach((id, artifact) -> System.err.println("Collision: " + id));
* Map<String, List<Artifact>> collisionMap = listener.getArtifactsCollisionMap(artifacts);
* collisionMap.forEach((id, artifacts) -> System.err.println("Collision: " + id + " -> " + artifacts));
* }</pre>
*
* @param artifacts the list of detected {@link Artifact} instances
* @return a map of colliding artifact identifiers to their {@link Artifact} instances
* @return a map of colliding artifact identifiers to all their colliding {@link Artifact} instances
*/
Map<String, Artifact> getArtifactsCollisionMap(List<Artifact> artifacts) {
Map<String, List<Artifact>> getArtifactsCollisionMap(List<Artifact> artifacts) {
int size = size(artifacts);
Map<String, Artifact> artifactsCollisionMap = newLinkedHashMap(size);
Set<String> ids = newLinkedHashSet(size);
Map<String, Artifact> seenArtifacts = newLinkedHashMap(size);
Map<String, List<Artifact>> artifactsCollisionMap = newLinkedHashMap(size);
for (int i = 0; i < size; i++) {
Artifact artifact = artifacts.get(i);
String id = buildId(artifact);
if (!ids.add(id)) {
artifactsCollisionMap.put(id, artifact);
Artifact firstSeen = seenArtifacts.putIfAbsent(id, artifact);
if (firstSeen != null) {
artifactsCollisionMap.computeIfAbsent(id, k -> {
List<Artifact> list = new ArrayList<>();
list.add(firstSeen);
return list;
}).add(artifact);
}
}
return artifactsCollisionMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ void initializePropertySources(MutablePropertySources propertySources) {
String name = propertySource.getName();
try {
PropertySource originTrackedPropertySource = createOriginTrackedPropertySource(propertySource);
propertySources.replace(name, originTrackedPropertySource);
if (originTrackedPropertySource != null) {
propertySources.replace(name, originTrackedPropertySource);
}
} catch (IOException e) {
logger.error("Failed to create the origin tracked PropertySource[name : '{}', class : '{}']",
name, propertySource.getClass().getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ void testDiagnose() {
@Test
void testGetArtifactsCollisionMap() {
List<Artifact> artifacts = createArtifacts();
Map<String, Artifact> artifactsCollisionMap = this.listener.getArtifactsCollisionMap(artifacts);
Map<String, List<Artifact>> artifactsCollisionMap = this.listener.getArtifactsCollisionMap(artifacts);
assertEquals(1, artifactsCollisionMap.size());
assertTrue(artifactsCollisionMap.containsKey("test-artifact"));
assertEquals(2, artifactsCollisionMap.get("test-artifact").size());
}

private List<Artifact> createArtifacts() {
Expand Down
Loading