Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Async Spring annotation doesn't work

I have a method that must create a zip and mat file from the original file uploaded from the user. So I decided to store only the original file and then, in an async task I would like to create the other two files. I read that the @Async annotation has two limit: 1)Only on public method 2)The @Async method must be in a differet object respect the caller class. So I create a new class and put in it my async method but it still doens't work. This is the class that calls the async method:

@Service
public class FleetAcquisitionServicesImpl implements FleetAcquisitionServices{

    @Autowired
    private DatabaseAcquisitionServices databaseAcquisitionServices;
    @Autowired
    private DatabaseFleetsAndCarsServices databaseFleetsAndCarsServices;

    @Autowired
    private FleetFolderName fleetFolderName; 

    private static final int NUMBER_OF_SHEET=4;
    @Override
    public ArrayList<String> uploadFiles(MultipartFile[] openedFiles, Integer idFleet, Integer idCar, Integer initialKm) throws FileUploadException, FileEmptyException{
        ArrayList<String> filesName=new ArrayList<String>();
        String fileName=null;
        String carPath=null;
        for (MultipartFile openedFile:openedFiles){
            if (!openedFile.isEmpty()) {
                //Copy the file into path specified
                fileName = openedFile.getOriginalFilename();
                try {
                    //Get the path where to store the file
                    Fleet fleet=databaseFleetsAndCarsServices.getFleetById(idFleet);
                    Car car=databaseFleetsAndCarsServices.getCarById(idCar);
                    carPath= fleetFolderName.createCarName(fleet, car);
                    if (FilenameUtils.getExtension(fileName).equals("dat")){
                        fileName = FilenameUtils.removeExtension(fileName)+"_km"+initialKm;
                        //write dat file
                        openedFile.transferTo(new File(carPath +"/"+ fileName+".dat"));                 
                        ZipAndMat.createZipAndMat(carPath,fileName);
                    }else
                        openedFile.transferTo(new File(carPath +"/"+ fileName));
                } catch (Exception e) {
                    throw new FileUploadException("you failed to upload " + fileName,e);
                }
                filesName.add(carPath +"/"+ fileName);
            } else {
                throw new FileEmptyException("your file is empty " + openedFile.getOriginalFilename());
            }
        }
        return filesName;
    }

ZipAndMat.createZipAndMat(carPath,fileName)

is the async method and it is here:

package com.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Future;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;

import com.mathworks.toolbox.javabuilder.MWException;

import dataconversion.Converter;

public class ZipAndMat {


    @Async
    public static Future<String> createZipAndMat(String filePath, String fileName){
        try {
            Thread.sleep(20000L);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        //Open file
        Path path = Paths.get(filePath, fileName + ".dat");
        try {
            //Create zip
            byte[] zip = zipBytes(Files.readAllBytes(path),fileName+".dat");
            Files.write(Paths.get(filePath +"/"+ fileName+".zip"), zip);
            //create mat file
            Converter objConv = new Converter();
            objConv. dat2MatConversion(filePath +"/", fileName + ".dat", 0.2);
        } catch (IOException e) {
            return new AsyncResult<String>("Zip not created");
        } catch (MWException e){
            return new AsyncResult<String>("Mat not created");
        }
        return new AsyncResult<String>("Zip created");
    }

    /**
     * Convert a file into zip file keeping the same name
     * @param filename
     * @param input
     * @return
     * @throws IOException
     */
    private static byte[] zipBytes( byte[] input, String filename) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ZipOutputStream zos = new ZipOutputStream(baos);
        ZipEntry entry = new ZipEntry(filename);
        entry.setSize(input.length);
        zos.putNextEntry(entry);
        zos.write(input);
        zos.closeEntry();
        zos.close();
        return baos.toByteArray();
    }

}

I tried tu but @EnableAsync both the caller class and on the confiuration class but it doesn't works. What is wrong in my code? the static method? Thanks

like image 497
luca Avatar asked May 29 '26 20:05

luca


1 Answers

You need the following things:

  1. @EnableAsync on a configuration class to enable async processing in Spring.
  2. @Service or @Component on your ZipAndMat class to discover it as a Spring component.
  3. Change your createZipAndMat method so it's not static.
  4. Autowire this new Spring component in your FleetAcquisitionServicesImpl like this:

    @Autowired private ZipAndMat zipAndMat;

Then, instead of invoking the static method ZipAndMat.createZipAndMat(carPath,fileName); you'll need to invoke it on the autowired spring component instance like this:

zipAndMat.createZipAndMat(carPath,fileName);
like image 166
Nándor Előd Fekete Avatar answered Jun 01 '26 14:06

Nándor Előd Fekete



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!