Ho creato un plug-in di eclissi che si aggancia all'azione di salvataggio per creare un file javascript con il compilatore goolge. Vedi i file qui sotto. Che ha funzionato fino all'eclisse 3.7.2. Sfortunatamente ora in eclissi 4.2.1 sembra che questo crei un ciclo infinito a volte. Il lavoro "compile .min.js" (riga 64 in ResourceChangedListener.java) sembra essere la causa. Risulta nel caso in cui il workspace inizia a costruire più e più volte. Immagino che questo sia dovuto al fatto che quel lavoro crea o modifica un file che attiva di nuovo il build dell'area di lavoro, che attiva di nuovo il lavoro che attiva la compilazione e così via. Ma non riesco a capire come prevenirlo.Il plugin eclipse non funziona dopo l'aggiornamento a juno (eclipse 4)
// Activator.java
package closure_compiler_save;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "closure-compiler-save"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
Activator.plugin = this;
ResourceChangedListener listener = new ResourceChangedListener();
ResourcesPlugin.getWorkspace().addResourceChangeListener(listener);
}
@Override
public void stop(BundleContext context) throws Exception {
Activator.plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}
// ResourceChangedListener.java
package closure_compiler_save;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
public class ResourceChangedListener implements IResourceChangeListener {
public void resourceChanged(IResourceChangeEvent event) {
if (event.getType() != IResourceChangeEvent.POST_CHANGE)
return;
IResourceDelta delta = event.getDelta();
try {
processDelta(delta);
} catch (CoreException e) {
e.printStackTrace();
}
}
// find out which class files were just built
private void processDelta(IResourceDelta delta) throws CoreException {
IResourceDelta[] kids = delta.getAffectedChildren();
for (IResourceDelta delta2 : kids) {
if (delta2.getAffectedChildren().length == 0) {
if (delta.getKind() != IResourceDelta.CHANGED)
return;
IResource res = delta2.getResource();
if (res.getType() == IResource.FILE && "js".equalsIgnoreCase(res.getFileExtension())) {
if (res.getName().contains("min"))
return;
compile(res);
}
}
processDelta(delta2);
}
}
private void compile(final IResource res) throws CoreException {
final IPath fullPath = res.getFullPath();
final IPath fullLocation = res.getLocation();
final String fileName = fullPath.lastSegment().toString();
final String outputFilename = fileName.substring(0, fileName.lastIndexOf(".")).concat(".min.js");
final String outputPath = fullPath.removeFirstSegments(1).removeLastSegments(1).toString();
final IProject project = res.getProject();
final IFile newFile = project.getFile(outputPath.concat("/".concat(outputFilename)));
Job compileJob = new Job("Compile .min.js") {
public IStatus run(IProgressMonitor monitor) {
byte[] bytes = null;
try {
bytes = CallCompiler.compile(fullLocation.toString(), CallCompiler.SIMPLE_OPTIMIZATION).getBytes();
InputStream source = new ByteArrayInputStream(bytes);
if (!newFile.exists()) {
newFile.create(source, IResource.NONE, null);
} else {
newFile.setContents(source, IResource.NONE, null);
}
} catch (IOException e) {
e.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
}
return Status.OK_STATUS;
}
};
compileJob.setRule(newFile.getProject()); // this will ensure that no two jobs are writing simultaneously on the same file
compileJob.schedule();
}
}
Da dove viene CallCompiler? Si tratta di un vaso di terze parti che hai incluso nella cartella del tuo plugin Eclipse, magari in una directory/lib? Se lo hai fatto, assicurati che il jar di terze parti si trovi sul percorso di runtime di Manifest.mf (modificato nell'editor manifest.mf) e assicurati anche che su build.properties nel bin.include che includa quel jar di terze parti . – gamerson
CallCompiler è la mia classe, chiama il compilatore di chiusura per il file in questione. La logica in quella classe funziona. Ho anche un menu a comparsa che attiva il processo di minimizzazione per un file con la stessa classe CallCompiler. Solo che il processo di salvataggio automatico non funzionerà più. – DarsVaeda
Strano, quindi funziona nel workspace/runtime worksbench ma non nell'installazione standalone. L'ho visto molte volte. Osservando il codice, fare attenzione con la chiamata res.getLocation(). Ho visto che restituire null in alcune situazioni. Il mio unico suggerimento ora è quello di aggiungere altro output di debug per il metodo compile() per vedere quali sono le differenze tra la versione di sviluppo e la versione installata. – gamerson