Common Java Backend Code Smells and Bugs: Real‑World Cases and Fixes
The article presents a collection of typical Java backend coding mistakes—ranging from misused ternary operators and poor parameter validation to logging pitfalls, dead code, improper exception handling, AOP self‑invocation issues, Redis resilience problems, and Excel file upload bugs—along with concrete examples, images, and corrected code snippets to help developers avoid and fix them.
The author recounts a stressful experience of inheriting a colleague's code, discovering numerous hidden bugs and bad practices, and decides to compile a list of common Java backend issues with explanations and fixes.
Case 1 – Misused Ternary Operator The original code relied on a ternary expression without proper parentheses, leading to incorrect evaluation order. The author shows the erroneous snippet (image) and the corrected version with explicit parentheses to ensure the intended logic.
Case 2 – Parameter Validation and AOP Missing or incorrect parameter checks are highlighted, especially when using AOP for validation. The article includes screenshots of problematic code and emphasizes the need for proper annotations and validation logic.
Case 3 – Unclear Log Placeholders Log statements with ambiguous placeholders are discussed, pointing out that many developers ignore API documentation and misuse placeholder syntax, which hampers log readability.
Case 4 – Dead or Unused Code Code fragments that serve no purpose are identified; the author advises removing or commenting them out to avoid confusion during maintenance.
Case 5 – Improper Error‑Code Handling in Service Layer The article warns against returning raw error codes from service methods or printing them inside the method. It recommends using custom exceptions and letting a global exception handler manage error codes and messages.
Case 6 – Self‑Invoking Aspect Failure A common AOP pitfall where an aspect does not apply to self‑invoked methods is described. The solution is to inject the bean itself and call through the proxy.
Case 7 – Redis/Redisson Resilience Issues When Redis becomes unavailable, the application may crash. The author provides a cache‑first method that falls back to the database and wraps Redis calls in try‑catch blocks. The corrected code is shown below:
@Autowired
private RedissonClient redissonClient;
public BigDecimal getIntervalQty(int itemId, Date startDate, Date endDate) {
String cacheKey = "dashboard:intervalQty:" + itemId + "-" + startDate + "-" + endDate;
RBucket
bucket = redissonClient.getBucket(cacheKey);
BigDecimal cacheValue = bucket.get();
if (cacheValue != null) {
return cacheValue;
} else {
BigDecimal intervalQty = erpInfoMapper.getIntervalQty(itemId, startDate, endDate);
BigDecimal res = Optional.ofNullable(intervalQty).orElse(BigDecimal.valueOf(0)).setScale(2, RoundingMode.HALF_UP);
bucket.set(res, 16, TimeUnit.HOURS);
return res;
}
}
public String getProductLine(String itemNo) {
String cacheKey = "order:getProductLine:" + itemNo;
String cacheValue = null;
RBucket
bucket = redissonClient.getBucket(cacheKey);
try {
cacheValue = bucket.get();
} catch (Exception e) {
log.error("redis connection exception", e);
}
if (cacheValue != null) {
return cacheValue;
} else {
String res = ptmErpMapper.getProductLine(itemNo);
bucket.set(res, 16, TimeUnit.HOURS);
return res;
}
}Case 8 – Excel File Upload Bug An asynchronous import component failed because the temporary MultipartFile was deleted after the main thread finished, causing "file not found" errors. The fix is to convert the MultipartFile to a local temporary File before starting async processing and delete it after use. Relevant code snippets are provided:
/**
* @param mFile Uploaded file
* @param identifier Unique identifier for PTM2.0 file list
*/
public ExcelUploadResDTO commonImportExcel(MultipartFile mFile, String identifier) {
if (mFile.isEmpty()) {
throw new PtmException("Uploaded Excel file cannot be empty");
}
String fileName = mFile.getOriginalFilename();
if (StringUtils.isEmpty(fileName)) {
throw new PtmException("Excel name cannot be empty");
}
if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) {
throw new PtmException("Invalid Excel format");
}
String token = getToken(true, 10);
if (mFile.getSize() <= 0) {
throw new PtmException("Uploaded file is empty");
}
String fileDir = commonProperties.getFileDir();
File filePathExist = new File(fileDir);
if (!filePathExist.exists()) {
if (!filePathExist.mkdirs()) {
return null;
}
}
File file = new File(fileDir + mFile.getOriginalFilename());
try (BufferedInputStream bis = new BufferedInputStream(mFile.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
int bytesRead;
byte[] buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
log.error("multipartFileToFile failed", e);
}
String fileId = ExternalApi.uploadFileServer(token, file, splicingFileServerUrl("upload"));
long ptmFileId = createPtmFile(fileId, fileName, identifier, true);
return new ExcelUploadResDTO(ptmFileId, file);
}
public List
readFile(File file, Class
clazz, boolean headCheck) {
ExcelListener excelListener = new ExcelListener();
EasyExcel.read(file, clazz, excelListener).sheet().doRead();
ExcelAnalyzeResDTO excelData = excelListener.getExcelData();
if (headCheck) {
checkHeadRight(clazz, excelData);
}
String dateError = excelData.getDateError();
log.info("File parsing completed, deleting file={}, result={}", file.getName(), file.delete());
if (!StringUtils.isEmpty(dateError)) {
throw new PtmException(dateError);
} else {
return excelData.getExcelDataList();
}
}The author notes that this Excel import component has been stable for two years after multiple iterations.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.