duplicate `BundleUtil` class to avoid reflection error on console update #7198
This commit is contained in:
parent
107c3dec42
commit
2d2b368a78
|
@ -1,7 +1,6 @@
|
|||
package com.rusefi;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.core.io.BundleUtil;
|
||||
import com.rusefi.core.net.ConnectionAndMeta;
|
||||
import com.rusefi.core.preferences.storage.PersistentConfiguration;
|
||||
import com.rusefi.core.ui.FrameHelper;
|
||||
|
@ -10,6 +9,7 @@ import com.rusefi.io.serial.BaudRateHolder;
|
|||
import com.rusefi.maintenance.*;
|
||||
import com.rusefi.ui.BasicLogoHelper;
|
||||
import com.rusefi.ui.LogoHelper;
|
||||
import com.rusefi.ui.duplicates.ConsoleBundleUtil;
|
||||
import com.rusefi.ui.util.HorizontalLine;
|
||||
import com.rusefi.ui.util.URLLabel;
|
||||
import com.rusefi.ui.util.UiUtils;
|
||||
|
@ -209,7 +209,7 @@ public class StartupFrame {
|
|||
|
||||
JPanel rightPanel = new JPanel(new VerticalFlowLayout());
|
||||
|
||||
if (BundleUtil.readBundleFullNameNotNull().getTarget().contains("proteus_f7")) {
|
||||
if (ConsoleBundleUtil.readBundleFullNameNotNull().getTarget().contains("proteus_f7")) {
|
||||
String text = "WARNING: Proteus F7";
|
||||
URLLabel urlLabel = new URLLabel(text, "https://github.com/rusefi/rusefi/wiki/F7-requires-full-erase");
|
||||
new Timer(500, new ActionListener() {
|
||||
|
@ -252,7 +252,7 @@ public class StartupFrame {
|
|||
final String textAlign,
|
||||
final Supplier<Integer> minWidthSupplier
|
||||
) {
|
||||
final String nextBranchName = BundleUtil.readBundleFullNameNotNull().getNextBranchName();
|
||||
final String nextBranchName = ConsoleBundleUtil.readBundleFullNameNotNull().getNextBranchName();
|
||||
if (nextBranchName != null && !nextBranchName.isBlank()) {
|
||||
final JLabel newReleaseAmmomceMessage = new JLabel(
|
||||
String.format(
|
||||
|
@ -287,7 +287,7 @@ public class StartupFrame {
|
|||
jLabel.setForeground(Color.red);
|
||||
} else {
|
||||
final Date binaryModificationDate = new Date(binaryModificationTimestamp);
|
||||
final String branchNameToDisplay = BundleUtil.readBundleFullNameNotNull().getBranchName();
|
||||
final String branchNameToDisplay = ConsoleBundleUtil.readBundleFullNameNotNull().getBranchName();
|
||||
jLabel = new JLabel(String.format(
|
||||
"<html><center>%s files<br/>%s</center></html>",
|
||||
branchNameToDisplay,
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package com.rusefi.ui.duplicates;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
|
||||
// `com.rusefi.ui.duplicates.ConsoleBundleUtil` class duplicates `com.rusefi.core.io.BundleUtil` class to avoid crash
|
||||
// on console update (caused by missed `BundleInfo.getNextBranchName` method) - see `readme.md` for details.
|
||||
// TODO: in June 2025 we need to get rid of this class and to replace its usage with `com.rusefi.core.io.BundleUtil`.
|
||||
public class ConsoleBundleUtil {
|
||||
private static final Logging log = getLogging(ConsoleBundleUtil.class);
|
||||
|
||||
private static final String DEVELOPMENT = "development";
|
||||
private static final String BRANCH_REF_FILE = "release.txt";
|
||||
|
||||
/**
|
||||
* @return null in case of error
|
||||
*/
|
||||
public static List<@NotNull String> readBundleFullName() {
|
||||
File f = new File(BRANCH_REF_FILE);
|
||||
if (!f.exists()) {
|
||||
log.error(BRANCH_REF_FILE + " not found");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Files.readAllLines(f.toPath());
|
||||
} catch (InvalidPathException | IOException e) {
|
||||
log.error("Error reading bundle name", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BundleInfo readBundleFullNameNotNull() {
|
||||
List<@NotNull String> info = readBundleFullName();
|
||||
if (info == null)
|
||||
return BundleInfo.UNKNOWN;
|
||||
return parse(info);
|
||||
}
|
||||
|
||||
public static String getBundleTarget() {
|
||||
return readBundleFullNameNotNull().getTarget();
|
||||
}
|
||||
|
||||
public static BundleInfo parse(List<@NotNull String> info) {
|
||||
Map<String, String> keyValues = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
for (String line : info) {
|
||||
String[] pair = line.split("=", 2);
|
||||
keyValues.put(pair[0], pair[1]);
|
||||
}
|
||||
String target = keyValues.get("platform");
|
||||
String branchName = keyValues.get("release");
|
||||
String nextBranchName = keyValues.get("nextRelease");
|
||||
if (target == null || branchName == null) {
|
||||
log.info(BRANCH_REF_FILE + " says " + keyValues);
|
||||
return BundleInfo.UNKNOWN;
|
||||
}
|
||||
return new ConsoleBundleUtil.BundleInfo(branchName, nextBranchName, target);
|
||||
}
|
||||
|
||||
public static class BundleInfo {
|
||||
static final BundleInfo UNKNOWN = new BundleInfo("unknown", null, "unknown");
|
||||
|
||||
private final String branchName;
|
||||
private final String nextBranchName;
|
||||
private final String target;
|
||||
|
||||
public BundleInfo(String branchName, String nextBranchName, String target) {
|
||||
this.branchName = Objects.requireNonNull(branchName, "branchName");
|
||||
this.nextBranchName = nextBranchName;
|
||||
this.target = Objects.requireNonNull(target, "target");
|
||||
}
|
||||
|
||||
public static boolean isUndefined(BundleInfo bundleInfo) {
|
||||
return bundleInfo == UNKNOWN;
|
||||
}
|
||||
|
||||
public String getBranchName() {
|
||||
return branchName;
|
||||
}
|
||||
|
||||
public String getNextBranchName() {
|
||||
return nextBranchName;
|
||||
}
|
||||
|
||||
public boolean isMaster() {
|
||||
return DEVELOPMENT.equals(branchName);
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BundleInfo{" +
|
||||
"branchName='" + branchName + '\'' +
|
||||
"nextBranchName='" + nextBranchName + '\'' +
|
||||
", target='" + target + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getUiLabel() {
|
||||
return target + "." + branchName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
We have a problem with classes that are used by both `rusefi_autoupdate.jar` and `rusefi_console.jar`: if we add a new method to such class and use it in `rusefi_console.jar` than we get reflection exception after update.
|
||||
|
||||
The reason is that `rusefi_autoupdate.jar` contains an obsolete version of the class without new method, but a new version `rusefi_console.jar` tries to call the missed method and crashes.
|
||||
|
||||
This is not a total catastrophe, because after crash `rusefi_console.jar` can be restarted successfully, but we want to reduce number of users experiencing this problem.
|
||||
|
||||
The suggested solution is to temporarily duplicate problematic classes in `com.rusefi.ui.duplicates` package and at first to use this duplicated classes in `rusefi_console.jar` instead of original classes that is used in `rusefi_autoupdate.jar`.
|
||||
|
||||
After the majority of users have already updated their console, we could get rid of duplicated classes and replace them with the original class used by `rusefi_autoupdate.jar`.
|
||||
|
||||
We will still have a few users that haven't updated their console and they will experience a crash on console update, but I do not think that it is serious problem.
|
Loading…
Reference in New Issue