I am building a web interface using Vaadin that displays the list of objects that I have in my Amazon S3 Bucket in a Vaadin Grid component. My service works fine but I get a NullPointerException every time I try to add the list of objects from my S3 Service to the grid.
Here is the S3 Service: S3 Service
I tested my service using the spring CommandLineRunner interface on a test class. Here is the test class: Test Class
Whenever I run the application, I see the list of items in my S3 Bucket listed on the console: Console Output
But the same service throws a NullPointerException on the browser whenever i try to add the list items to the Vaadin Grid and a BeanCreationException gets logged on the console:
BeanCreationException NullPointerException
Here is S3Service.java
@Service
public class S3Service {
@Autowired
private AmazonS3 s3Client;
@Value("${aws.s3.bucket.name}")
private String bucketName;
public List<String> listObjects() {
ObjectListing objectListing=s3Client.listObjects(bucketName);
return objectListing.getObjectSummaries()
.stream()
.map(S3ObjectSummary::getKey)
.collect(Collectors.toList());
}
}
TestFeatureClass.java
@Component
public class TestFeatureClass implements CommandLineRunner {
@Autowired
private S3Service s3Service;
@Override
public void run(String... args) throws Exception {
System.out.println(s3Service.listObjects());
}
}
DocumentManagementSystemView.java
@PageTitle("Documents")
@Route(value = "api/v1/files/list",layout = MainLayout.class)
@Uses(Icon.class)
public class DocumentManagementSystemView extends VerticalLayout {
@Autowired
public S3Service s3Service;
Grid<String> grid;
public DocumentManagementSystemView() {
this.grid=new Grid<>(String.class,false);
configureGrid();
add(grid);
updateList();
}
private void configureGrid() {
grid.setColumns("Filename");
}
private void updateList() {
grid.setItems(s3Service.listObjects());
}
}
First issue I see is that you should use constructor-injection instead of field-injection, if you intend to use the injected bean during constructor. This should fix your NullPointerException.
@PageTitle("Documents")
@Route(value = "api/v1/files/list",layout = MainLayout.class)
@Uses(Icon.class)
public class DocumentManagementSystemView extends VerticalLayout {
private S3Service s3Service;
private Grid<String> grid;
public DocumentManagementSystemView(S3Service s3Service) {
this.s3Service = s3Service;
...
}
}
Second issue I see is that you use grid.setColumns("Filename")
on a Grid of type String. This will try to find a property called 'Filename' in the String class and render that in the column. I assume you wanted a column with the header "Filename". Since the Grid is of Type String, and you want to display that string in this column, you should provide a valueprovider that returns the whole item/string: str -> str
or Function.identity()
they are basically the same thing, you choose whichever is more readable to you. more info
grid.addColumn(str -> str).setHeader("Filename");