Connect to MinIO using Java

Updated: 2024-04-01

MinIO is a popular alternative to AWS S3 and Azure Storage, it's compatible with the S3 protocol. It's big advantage is that it can be installed on your own servers ar in the cloud using docker (e.g. using Virtuozzo PAAS / Jelastic).

Connection with Java

pom.xml

In you pom.xml you can add the dependency:

<dependency> 
    <groupId>io.minio</groupId> 
    <artifactId>minio</artifactId> 
    <version>8.5.9</version> 
</dependency> 

MinioClient

In my case I created a Bean to store the MinioClient:

import io.minio.MinioClient; 
... 
 
@Configuration 
public class MinioConfig { 
 
  @Bean 
  public MinioClient getMinioClient() { 
    return MinioClient.builder() 
    .endpoint("http://my-server") 
    .credentials("username", "password") 
    .build(); 
  } 
} 

For a production environment you should store these parameters outside of the code.

MinIO Service, list files and read content

To list the files and read the content I created a @Service

import io.minio.GetObjectArgs; 
import io.minio.ListObjectsArgs; 
import io.minio.MinioClient; 
import io.minio.Result; 
import io.minio.messages.Item; 
 
@Service 
@AllArgsConstructor 
@Slf4j 
public class MinioService { 
 
    private final MinioClient getMinioClient;    
    ... 
} 

MinIO uses Items objects to store the information of the files we want to access.

In our case, we stored all the files in a hierarchical structure of folders inside a blog-posts bucket.

 public listMinioItems() { 
     
  Iterable<Result<Item>> results = getMinioClient.listObjects( 
    ListObjectsArgs.builder() 
      .bucket("blog-posts") 
      .recursive(true) 
      .build()); 

Now that I have the list of files I want to filter them and use only the markdown files. These files will be converted in blog posts.

To filter the items we use the objectName property.

results.forEach(itemResult -> { 
  try { 
    Article article; 
    if (itemResult.get().objectName().endsWith(".md")) { 
        article = buildArticle(itemResult.get()); 
    if (!(article.getPublished() != null 
     && article.getPublished().equals("false"))) { 
      articleList.add(article); 
    } 
  } 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
}); 
return articleList; 
} 

Create a List from an Item

The MinIO objects need to be transformed in a List of Strings (lines) for this use case.

In this case we have to use the MinioClient again to get a specific file and transform it.

We need to use GetObjectArs to get the Object represented by the Item and stream it into a list.

public Article buildArticle(Item minioItem) throws Exception { 
  InputStream stream = getMinioClient().getObject( 
    GetObjectArgs.builder() 
      .bucket("blog-posts") 
      .object(minioItem.objectName()) 
      .build() 
); 
List<String> content = createLines(stream); 

If the UI doesn't show your files and is 'loading' forever

This issue seems to happen if you are not using a dedicated IP to access MinIO. In my tests I succeeded to solve the problem assigning an IP to the Jelastic instance. This is annoying because it requires extra configuration and extra costs. With Jelastic (Virtuozzo PAAS) I had an issue using https too. I guess that is more related with the PAAS than with MinIO.

My opinion

I had a few issues using MinIO, it could be caused by the implementation done in Jelastic / Virtuozzo PAAS. Besides the issues the usage and the integration with Java was easy and the performance good.


Fullstack Angular / Java application quick start guide.
WebApp built by Marco using SpringBoot 3.2.4 and Java 21. Hosted in Switzerland (GE8).