Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injection of List<Resource> is inconsistent with Resource[] #24845

Closed
quaff opened this issue Apr 2, 2020 · 6 comments
Closed

Injection of List<Resource> is inconsistent with Resource[] #24845

quaff opened this issue Apr 2, 2020 · 6 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@quaff
Copy link
Contributor

quaff commented Apr 2, 2020

Normally it's safe to change type from array to list, but it's not for Resource.

@Value("${resources:file:/tmp/*.text}")
Resource[] resourceArray;  // multiple FileSystemResource

@Value("${resources:file:/tmp/*.text}")
List<Resource> resourceList; // only one FileUrlResource

here is the full test

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;

import test.ResourceInjectionTest.TestConfiguration;

@RunWith(SpringRunner.class)
@TestPropertySource(properties = { "resources=file:/tmp/*.text" })
@ContextConfiguration(classes = TestConfiguration.class)
public class ResourceInjectionTest {

	private static File[] files;

	@Autowired
	private TestConfiguration testConfiguration;

	@BeforeClass
	public static void setup() throws IOException {
		files = new File[2];
		files[0] = new File("/tmp", "a.text");
		files[1] = new File("/tmp", "b.text");
		for (File f : files)
			f.createNewFile();
	}

	@AfterClass
	public static void cleanup() {
		for (File f : files)
			f.delete();
	}

	@Test
	public void testInjection() {
		assertEquals(2, testConfiguration.resourceArray.length); // two FileSystemResource
		assertEquals(2, testConfiguration.resourceList.size()); // one FileUrlResource
	}

	static class TestConfiguration {
		
		@Value("${resources}")
		Resource[] resourceArray;

		@Value("${resources}")
		List<Resource> resourceList;
		
	}
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 2, 2020
@sbrannen sbrannen added the in: core Issues in core modules (aop, beans, core, context, expression) label Apr 2, 2020
@sbrannen
Copy link
Member

sbrannen commented Apr 2, 2020

Thanks for raising the issue.

I've been able to reproduce this against master using the following simplified test case.

package org.springframework.test;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

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

@SpringJUnitConfig
class ResourceInjectionTests {

	@BeforeAll
	static void setup() throws IOException {
		List<File> files = Arrays.asList(new File("/tmp", "a.text"), new File("/tmp", "b.text"));
		for (File file : files) {
			file.createNewFile();
			file.deleteOnExit();
		}
	}


	@Value("file:/tmp/*.text")
	Resource[] resourceArray;

	@Value("file:/tmp/*.text")
	List<Resource> resourceList;


	@Test
	void testInjection() {
		assertThat(resourceArray).as("array").hasSize(2); // two FileSystemResource
		assertThat(resourceList).as("list").hasSize(2); // one FileUrlResource
	}


	@Configuration
	static class Config {
	}

}

I assume it has something to do with the fact that a ResourceArrayPropertyEditor is probably used to handle the array; whereas, the list is likely handled using a mechanism that does not treat the string as a resource pattern.

@sbrannen
Copy link
Member

sbrannen commented Apr 2, 2020

Indeed, the difference is that a ResourceArrayPropertyEditor is used to handle the array case; whereas, a CustomCollectionEditor is used to handle the list case.

The former internally uses a ResourcePatternResolver to expand the pattern into the 2 files in the filesystem; whereas, the latter simply treats the pattern as a simple string without expansion.

@encircled
Copy link
Contributor

encircled commented Apr 7, 2020

This reminds me that CustomCollectionEditor does not support parsing of multiple values either (like @Value("1,2,3") List<Integer> ints).

Is that intentional?

@sbrannen
Copy link
Member

sbrannen commented Apr 8, 2020

This reminds me that CustomCollectionEditor does not support parsing of multiple values either (like @Value("1,2,3") List<Integer> ints).

Is that intentional?

@encircled, That is currently not supported, but feel free to open a new issue to start a discussion on the topic.

@encircled
Copy link
Contributor

Nevermind my prev comment, I just realized it is actually possible to do so by adding the ConversionService bean to the context.
I can fix the initial issue if needed.

@sbrannen sbrannen assigned sbrannen and jhoeller and unassigned sbrannen May 11, 2020
@sbrannen sbrannen added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels May 11, 2020
@sbrannen sbrannen added this to the 5.x Backlog milestone May 11, 2020
@sbrannen
Copy link
Member

Team Decision: Assigned to 5.x backlog as a potential enhancement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

5 participants