2013-03-01 15 views
6

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(); 
    } 

} 

risposta

3

Dopo l'installazione ho un vuoto eclissare ambiente classico, avviato un nuovo progetto Plug-in Eclipse lì e ricreato tutti i file funziona di nuovo in parte. In questo ambiente che avvia una sessione di debug posso salvare i file .js e i file .min.js vengono creati automaticamente. Fin qui tutto bene! Ma quando installo il plugin sul mio reale ambiente di eclissi in via di sviluppo, il salvataggio automatico non funziona.

Almeno un passo in più!

Passaggio 2: Alcuni file non inclusi nella compilazione erano ovviamente necessari, come manifest. Non ho idea del motivo per cui sono stati deselezionati. Ad ogni modo sembra che sia appena stato creato un classico eclipse 4 vuoto e che il wizard del plugin di eclipse abbia risolto il mio problema originale. Mi piacerebbe ancora sapere qual è il problema attuale ...

+0

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

+0

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

+0

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