3

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

3
  • 1
    I know nothing specifically about spring, but a quick skim through spring.io/guides/gs/async-method shows that you need to call the method on a @Service - their examples use a non-static method. Otherwise, you are just invoking createZipAndMat as a plain old static method - there is no potential for asynchronicity. Are you sure your 2 requirements are sufficient? Commented Jan 20, 2016 at 11:19
  • ZipandMat should be a spring bean .. Commented Jan 20, 2016 at 11:25
  • I've tried adding @Component but it doesn't work Commented Jan 20, 2016 at 11:28

2 Answers 2

5

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); 
Sign up to request clarification or add additional context in comments.

2 Comments

removing static it works. I didn't find nothing about static with async annotation. Thank you
Yes. The kind of magic @EnableAsync does usually only applies to spring components. So you need @Component or @Service and normal instance method to enable Spring to do it's job. It's really worth to read more about what spring does and how, it pays off on the long run.
1

You need to do below thing to enable async

1.) @Service public class ZipAndMat ...

2.) Caller class should enable async call using @EnableAsync

@EnableAsync @Service public class FleetAcquisitionServicesImpl implements FleetAcquisitionServices

Please follow this link for more details https://spring.io/guides/gs/async-method/

1 Comment

I added '@Services' to ZipAndMat, '@EnableAsync' to FleetAcquisitionServicesImpl but I have to still wait that ZipAndMat end.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.