Skip to content

Commit

Permalink
Merge pull request #6743 from lahodaj/option-disable-nbjavac
Browse files Browse the repository at this point in the history
Adding ability to safely enable/disable module fragments (requires restart, obviously), and tweaking nbjavac so that it can be enable/disabled.
  • Loading branch information
lahodaj authored Jan 15, 2024
2 parents 7fc8a87 + da71927 commit 865b3f3
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private JPDASupport (JPDADebugger jpdaDebugger, ProcessIO pio) {

public static Test createTestSuite(Class<? extends TestCase> clazz) {
Configuration suiteConfiguration = NbModuleSuite.createConfiguration(clazz);
suiteConfiguration = suiteConfiguration.clusters(".*").enableModules(".*java.source.*").gui(false);
suiteConfiguration = suiteConfiguration.clusters(".*").enableModules(".*java.source.*").enableModules(".*libs.nbjavacapi.*").gui(false);
if (!(ClassLoader.getSystemClassLoader() instanceof URLClassLoader)) {
//when running on JDK 9+, to make the com.sun.jdi package dependency work, we need to make getPackage("com.sun.jdi") work
//for system CL's parent (which otherwise happily loads the VirtualMachineManager class,
Expand Down
1 change: 0 additions & 1 deletion java/java.source.base/manifest.mf
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ OpenIDE-Module: org.netbeans.modules.java.source.base
OpenIDE-Module-Implementation-Version: 6
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/source/base/Bundle.properties
OpenIDE-Module-Layer: org/netbeans/modules/java/source/base/layer.xml
OpenIDE-Module-Recommends: org.netbeans.libs.nbjavac
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ InstallStep_Header_Restart_Head=Restart NetBeans IDE to complete installation.
InstallStep_Header_Restart_Content=Restart NetBeans IDE to finish plugin installation.
UninstallStep_Header_Restart_Head=Restart NetBeans IDE to complete deactivation.
UninstallStep_Header_Restart_Content=Restart NetBeans IDE to finish plugin deactivation.
UninstallStep_Activate_Header_Restart_Head=Restart NetBeans IDE to complete activation.
UninstallStep_Activate_Header_Restart_Content=Restart NetBeans IDE to finish plugin activation.
InstallUnitWizardModel_Buttons_RestartNow=&Restart IDE Now
InstallUnitWizardModel_Buttons_RestartLater=Restart IDE &Later
InstallStep_InstallDone_Text=The NetBeans IDE Installer has successfully \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ CTL_UnpackingFile=Unpacking
CTL_DownloadingFile=Downloading
CTL_DeletingFiles=Uninstalling files...
CTL_DisablingFiles=Deactivating files...
CTL_EnablingFiles=Enabling files...
UpdaterFrame.jTextArea1.text=Update is in progress.\n\nPlease wait...
UpdaterFrame.textLabel.text=Preparing to Unpack
UpdaterFrame.Form.title=Updater
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public final class ModuleDeactivator extends Object {

public static final String TO_UNINSTALL = "to_uninstall.txt"; // NOI18N
public static final String TO_DISABLE = "to_disable.txt"; // NOI18N
public static final String TO_ENABLE = "to_enable.txt"; // NOI18N

public static final String CONFIG = "config"; // NOI18N
public static final String MODULES = "Modules"; // NOI18N
Expand Down Expand Up @@ -60,19 +61,22 @@ public void delete () {
}
}

public void disable () {
public void enableDisable(boolean enable) {
assert ! SwingUtilities.isEventDispatchThread () : "Cannot run in EQ";
context.setLabel (Localization.getBrandedString ("CTL_DisablingFiles"));
context.setLabel (enable ? Localization.getBrandedString ("CTL_EnablingFiles")
: Localization.getBrandedString ("CTL_DisablingFiles"));
Collection<File> allControlFiles = new HashSet<File> ();
for (File cluster : UpdateTracking.clusters (true)) {
allControlFiles.addAll (readFilesMarkedForDisableInCluster (cluster));
doDelete (getControlFileForMarkedForDisable (cluster));
doDelete (getDeactivateLater (cluster));
allControlFiles.addAll (readFilesMarkedForEnableDisableInCluster(cluster, enable));
doDelete (getControlFileForMarkedForEnableDisable(cluster, enable));
if (!enable) {
doDelete (getDeactivateLater (cluster));
}
}
context.setProgressRange (0, allControlFiles.size ());
int i = 0;
for (File f : allControlFiles) {
doDisable (f);
doEnableDisable(f, enable);
context.setProgressValue (i ++);
}
}
Expand All @@ -87,6 +91,11 @@ public static boolean hasModulesForDisable (File updateDir) {
return deactivateDir.exists () && deactivateDir.isDirectory () && Arrays.asList (deactivateDir.list ()).contains (TO_DISABLE);
}

public static boolean hasModulesForEnable (File updateDir) {
File deactivateDir = new File (updateDir, UpdaterDispatcher.DEACTIVATE_DIR);
return deactivateDir.exists () && deactivateDir.isDirectory () && Arrays.asList (deactivateDir.list ()).contains (TO_ENABLE);
}

public static File getDeactivateLater (File cluster) {
File file = new File (cluster,
UpdaterDispatcher.UPDATE_DIR + // update
Expand All @@ -103,11 +112,13 @@ public static File getControlFileForMarkedForDelete (File cluster) {
return file;
}

public static File getControlFileForMarkedForDisable (File cluster) {
public static File getControlFileForMarkedForEnableDisable (File cluster, boolean enable) {
String fileName = enable ? ModuleDeactivator.TO_ENABLE // to_enable.txt
: ModuleDeactivator.TO_DISABLE; // to_disable.txt
File file = new File (cluster,
UpdaterDispatcher.UPDATE_DIR + // update
UpdateTracking.FILE_SEPARATOR + UpdaterDispatcher.DEACTIVATE_DIR + // update/deactivate
UpdateTracking.FILE_SEPARATOR + ModuleDeactivator.TO_DISABLE); // to_disable.txt
UpdateTracking.FILE_SEPARATOR + fileName);
return file;
}

Expand Down Expand Up @@ -219,9 +230,9 @@ private static Set<File> readFilesMarkedForDeleteInCluster (File cluster) {
return toDelete;
}

private static Set<File> readFilesMarkedForDisableInCluster (File cluster) {
private static Set<File> readFilesMarkedForEnableDisableInCluster (File cluster, boolean enable) {

File mark4disableFile = getControlFileForMarkedForDisable (cluster);
File mark4disableFile = getControlFileForMarkedForEnableDisable(cluster, enable);
if (! mark4disableFile.exists ()) {
return Collections.emptySet ();
}
Expand All @@ -244,18 +255,24 @@ private static Set<File> readFilesMarkedForDisableInCluster (File cluster) {
private static String ENABLE_TAG = "<param name=\"enabled\">true</param>";
private static String DISABLE_TAG = "<param name=\"enabled\">false</param>";

private static void doDisable (File f) {
private static void doEnableDisable (File f, boolean enable) {
String expected = enable ? DISABLE_TAG : ENABLE_TAG;
String target = enable ? ENABLE_TAG : DISABLE_TAG;

String content = readStringFromFile (f);
int pos = content.indexOf (ENABLE_TAG);
assert pos != -1 : ENABLE_TAG + " must be contained in " + content;
int shift = ENABLE_TAG.length ();
String pre = content.substring (0, pos);
String post = content.substring (pos + shift);
String res = pre + DISABLE_TAG + post;
if (!content.contains(target)) {
int pos = content.indexOf(expected);
assert pos != -1 : expected + " must be contained in " + content;
int shift = expected.length ();
String pre = content.substring (0, pos);
String post = content.substring (pos + shift);

content = pre + target + post;
}
File configDir = new File (new File (UpdateTracking.getUserDir (), CONFIG), MODULES);
configDir.mkdirs ();
File dest = new File (configDir, f.getName());
writeStringToFile (res, dest);
writeStringToFile (content, dest);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
public final class UpdaterDispatcher implements Runnable {
private Boolean disable = null;
private Boolean enable = null;
private Boolean install = null;
private Boolean uninstall = null;

Expand Down Expand Up @@ -60,7 +61,12 @@ private void dispatch () {

// then disable
if (isDisableScheduled ()) {
new ModuleDeactivator(context).disable();
new ModuleDeactivator(context).enableDisable(false);
}

// then disable
if (isEnableScheduled()) {
new ModuleDeactivator(context).enableDisable(true);
}

// finally install/update
Expand All @@ -87,6 +93,13 @@ private boolean isDisableScheduled () {
return disable;
}

private boolean isEnableScheduled () {
if (enable == null) {
exploreUpdateDir ();
}
return enable;
}

private boolean isUninstallScheduled () {
if (uninstall == null) {
exploreUpdateDir ();
Expand All @@ -106,6 +119,7 @@ private void exploreUpdateDir () {
install = false;
uninstall = false;
disable = false;
enable = false;

// go over all clusters
for (File cluster : UpdateTracking.clusters (true)) {
Expand All @@ -123,6 +137,10 @@ private void exploreUpdateDir () {
if (disable == null || ! disable) {
disable = ModuleDeactivator.hasModulesForDisable (updateDir);
}
// enable
if (enable == null || ! enable) {
enable = ModuleDeactivator.hasModulesForEnable (updateDir);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@
*
* @author Jiri Rechtacek
*/
public final class ModuleDeleterImpl {
private static final ModuleDeleterImpl INSTANCE = new ModuleDeleterImpl();
public final class ModuleEnableDisableDeleteHelper {
private static final ModuleEnableDisableDeleteHelper INSTANCE = new ModuleEnableDisableDeleteHelper();
private static final String ELEMENT_MODULE = "module"; // NOI18N
private static final String ELEMENT_VERSION = "module_version"; // NOI18N
private static final String ATTR_LAST = "last"; // NOI18N
private static final String ATTR_FILE_NAME = "name"; // NOI18N

private static final Logger err = Logger.getLogger (ModuleDeleterImpl.class.getName ()); // NOI18N
private static final Logger err = Logger.getLogger (ModuleEnableDisableDeleteHelper.class.getName ()); // NOI18N

private Set<File> storageFilesForDelete = null;

public static ModuleDeleterImpl getInstance() {
public static ModuleEnableDisableDeleteHelper getInstance() {
return INSTANCE;
}

Expand All @@ -88,15 +88,19 @@ public boolean canDelete (ModuleInfo moduleInfo) {
}
}

public Collection<File> markForDisable (Collection<ModuleInfo> modules, ProgressHandle handle) {
public Collection<File> findControlFiles(Collection<ModuleInfo> modules, ProgressHandle handle) {
if (modules == null) {
throw new IllegalArgumentException ("ModuleInfo argument cannot be null.");
}

if (handle != null) {
handle.switchToDeterminate (modules.size() + 1);
}


return doFindControlFiles(modules, handle);
}

private Collection<File> doFindControlFiles(Collection<ModuleInfo> modules, ProgressHandle handle) {
Collection<File> configs = new HashSet<File> ();
int i = 0;
for (ModuleInfo moduleInfo : modules) {
Expand Down Expand Up @@ -125,18 +129,9 @@ public Collection<File> markForDelete (Collection<ModuleInfo> modules, ProgressH
handle.switchToDeterminate (modules.size () * 2 + 1);
}

Collection<File> configFiles = new HashSet<File> ();
int i = 0;
for (ModuleInfo moduleInfo : modules) {
Collection<File> configs = locateAllConfigFiles (moduleInfo);
assert configs != null : "Located config files for " + moduleInfo.getCodeName ();
assert ! configs.isEmpty () : configs + " config files must exists for " + moduleInfo.getCodeName ();
configFiles.addAll (configs);
err.log(Level.FINE, "Locate config files of " + moduleInfo.getCodeNameBase () + ": " + configs);
if (handle != null) {
handle.progress (++i);
}
}
Collection<File> configFiles = doFindControlFiles(modules, handle);
int i = configFiles.size();

getStorageFilesForDelete ().addAll (configFiles);

for (ModuleInfo moduleInfo : modules) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ private OperationSupportImpl() {
}

private static class ForEnable extends OperationSupportImpl {
private Collection<File> controlFileForEnable = null;
private Collection<UpdateElement> affectedModules = null;
@Override
public synchronized Boolean doOperation(ProgressHandle progress,
OperationContainer<?> container) throws OperationException {
Expand Down Expand Up @@ -128,21 +130,26 @@ public synchronized Boolean doOperation(ProgressHandle progress,
assert mm != null;

needsRestart = mm.hasToEnableCompatModules(modules);

final ModuleManager fmm = mm;
try {
fmm.mutex ().writeAccess (new ExceptionAction<Boolean> () {
@Override
public Boolean run () throws Exception {
return enable(fmm, modules);

if (!needsRestart) {
final ModuleManager fmm = mm;
try {
fmm.mutex ().writeAccess (new ExceptionAction<Boolean> () {
@Override
public Boolean run () throws Exception {
return enable(fmm, modules);
}
});
} catch (MutexException ex) {
Exception x = ex.getException ();
assert x instanceof OperationException : x + " is instanceof OperationException";
if (x instanceof OperationException) {
throw (OperationException) x;
}
});
} catch (MutexException ex) {
Exception x = ex.getException ();
assert x instanceof OperationException : x + " is instanceof OperationException";
if (x instanceof OperationException) {
throw (OperationException) x;
}
} else {
ModuleEnableDisableDeleteHelper helper = new ModuleEnableDisableDeleteHelper ();
controlFileForEnable = helper.findControlFiles(moduleInfos, progress);
}
} finally {
if (progress != null) {
Expand All @@ -155,7 +162,12 @@ public Boolean run () throws Exception {

@Override
public void doCancel () throws OperationException {
assert false : "Not supported yet";
if (controlFileForEnable != null) {
controlFileForEnable = null;
}
if (affectedModules != null) {
affectedModules = null;
}
}

private static boolean enable(ModuleManager mm, Set<Module> toRun) throws OperationException {
Expand All @@ -173,13 +185,36 @@ private static boolean enable(ModuleManager mm, Set<Module> toRun) throws Operat

@Override
public void doRestart (Restarter restarter, ProgressHandle progress) throws OperationException {
LifecycleManager.getDefault().markForRestart();
LifecycleManager.getDefault().exit();
if (controlFileForEnable != null) {
// write files marked to enable into a temp file
// Updater will handle it
Utilities.writeFileMarkedForEnable(controlFileForEnable);

// restart IDE
Utilities.deleteAllDoLater ();
LifecycleManager.getDefault ().exit ();
// if exit&restart fails => use restart later as fallback
doRestartLater (restarter);
} else {
LifecycleManager.getDefault().markForRestart();
LifecycleManager.getDefault().exit();
}
}

@Override
public void doRestartLater (Restarter restarter) {
LifecycleManager.getDefault().markForRestart();
if (controlFileForEnable != null) {
// write files marked to enable into a temp file
// Updater will handle it
Utilities.writeFileMarkedForEnable(controlFileForEnable);

// schedule module for restart
for (UpdateElement el : affectedModules) {
UpdateUnitFactory.getDefault().scheduleForRestart (el);
}
} else {
LifecycleManager.getDefault().markForRestart();
}
}
}

Expand Down Expand Up @@ -214,8 +249,8 @@ public synchronized Boolean doOperation(ProgressHandle progress,
}
}
assert mm != null;
ModuleDeleterImpl deleter = new ModuleDeleterImpl ();
controlFileForDisable = deleter.markForDisable (modules, progress);
ModuleEnableDisableDeleteHelper deleter = new ModuleEnableDisableDeleteHelper ();
controlFileForDisable = deleter.findControlFiles(modules, progress);
} finally {
if (progress != null) {
progress.finish();
Expand Down Expand Up @@ -354,7 +389,7 @@ public synchronized Boolean doOperation(ProgressHandle progress,
if (progress != null) {
progress.start();
}
ModuleDeleterImpl deleter = new ModuleDeleterImpl();
ModuleEnableDisableDeleteHelper deleter = new ModuleEnableDisableDeleteHelper();

List<? extends OperationInfo> infos = container.listAll ();
Set<ModuleInfo> moduleInfos = new HashSet<ModuleInfo> ();
Expand Down Expand Up @@ -446,7 +481,7 @@ public synchronized Boolean doOperation(ProgressHandle progress,
if (progress != null) {
progress.start();
}
ModuleDeleterImpl deleter = new ModuleDeleterImpl();
ModuleEnableDisableDeleteHelper deleter = new ModuleEnableDisableDeleteHelper();

List<? extends OperationInfo> infos = container.listAll ();
Set<ModuleInfo> moduleInfos = new HashSet<ModuleInfo> ();
Expand Down
Loading

0 comments on commit 865b3f3

Please sign in to comment.