dellermann / i18n-asset-pipeline

An asset-pipeline plugin for client-side i18n.
Apache License 2.0
3 stars 8 forks source link

Asset Pipeline 2.0 Support #2

Closed davydotcom closed 9 years ago

davydotcom commented 9 years ago

Added integration support for asset-pipeline 2.0 and resolves issue #1 (this is not backwards compatible with 1.9.x) If you want to take this a step farther you can move stuff out into a gradle binary project onto maven central for support with other frameworks as well.

Thanks

davydotcom commented 9 years ago

need the asset.specs file in META-INF/asset-pipeline/asset.specs to tell the new asset-pipeline which AssetFile interfaces your plugin provides.

David Estes

On December 5, 2014 at 5:15:21 AM, Daniel Ellermann (notifications@github.com) wrote:

Thanks for your work. Is removing web-app from .gitignore really necessary?

— Reply to this email directly or view it on GitHub.

dellermann commented 9 years ago

I found a problem: META-INF/asset-pipeline/asset.specs is not found by AssetSpecLoader if it is placed in folder web-app. Your plugins (e. g. coffee-grails-asset-pipeline) don't have the problem because they load another dependency (e. g. coffee-asset-pipeline) which isn't a Grails plugin and correctly copies resource META-INF/asset-pipeline/asset.specs to the classpath.

Do you know a way to publish META-INF/asset-pipeline/asset.specs to the classpath?

davydotcom commented 9 years ago

Whoops, thats my bad I used the META-INF assuming web-app in a plugin would grab it. Try moving the META-INF folder to the src/java folder. That seemed to work when I changed that locally

dellermann commented 9 years ago

Thanks, now I18nAssetFile is found. But there comes the next problem: I18nAssetFile cannot be initialized:

Caused by: java.lang.NoSuchFieldError: r$sfields
    at asset.pipeline.i18n.I18nAssetFile.<clinit>(I18nAssetFile.groovy)

Do you have any idea what this means? I'm desperate after hours of bug searching…

davydotcom commented 9 years ago

Its because your static fields on the AssetFile spec don't match the specification of the new AssetFile interface.

    static List<String> contentType
    static List<String> extensions
    static String compiledExtension
    static List<Class<Processor>> processors
dellermann commented 9 years ago

I already supposed that but it didn't work. I've pushed commit 0ae25379b7b6583021801c14b3ba6a504fca4961 with the latest changes. Any other ideas?

dellermann commented 9 years ago

While looking for the r$sfields error, would you please check if the static fields declared in AssetFile are correct? If I look at the compile code, the following is produced:

package asset.pipeline;

import asset.pipeline.fs.AssetResolver;
import java.io.InputStream;
import java.util.List;
import java.util.regex.Pattern;

public abstract interface AssetFile
{
  public static final List<String> contentType;
  public static final List<String> extensions;
  public static final String compiledExtension;
  public static final List<Class<Processor>> processors;

  public abstract AssetFile getBaseFile();

  public abstract String getEncoding();

  public abstract void setEncoding(String paramString);

  public abstract void setBaseFile(AssetFile paramAssetFile);

  public abstract InputStream getInputStream();

  public abstract String getParentPath();

  public abstract String getPath();

  public abstract String getName();

  public abstract AssetResolver getSourceResolver();

  public abstract String processedStream(AssetCompiler paramAssetCompiler);

  public abstract Pattern getDirectivePattern();
}

IMHO, because of the static fields are compiled final I cannot do something like this in my subclass:

class I18nAssetFile extends AbstractAssetFile {
    static String compiledExtension = 'js'
    static List<String> contentType = [
        'application/javascript', 'application/x-javascript', 'text/javascript'
    ]
    static List<String> extensions = ['i18n']
    static List<Class<Processor>> processors = [I18nProcessor]
}

I also tried the following approach:

class I18nAssetFile extends AbstractAssetFile {
    static {
        AssetFile.@compiledExtension = 'js'
        AssetFile.@contentType = [
            'application/javascript', 'application/x-javascript', 'text/javascript'
        ]
        AssetFile.@processors = [I18nProcessor]
        AssetFile.@extensions = ['i18n']
    };
}

But this doesn't work either. It seems, that the static initializer is not executed, because I get "processors is null".

Your help is really essential, because it prevents this plugin from working with version 2.0 of asset-pipeline.

davydotcom commented 9 years ago

Got sidetracked this week. I'll look at that tomorrow . someone else just implemented it fine so its gotta be something simple staring us in the face.

Sent from Surface

From: Daniel Ellermann Sent: ‎Wednesday‎, ‎December‎ ‎17‎, ‎2014 ‎4‎:‎40‎ ‎AM To: dellermann/i18n-asset-pipeline Cc: David Estes

While looking for the r$sfields error, would you please check if the static fields declared in AssetFile are correct? If I look at the compile code, the following is produced:

package asset.pipeline;

import asset.pipeline.fs.AssetResolver; import java.io.InputStream; import java.util.List; import java.util.regex.Pattern;

public abstract interface AssetFile { public static final List contentType; public static final List extensions; public static final String compiledExtension; public static final List<Class> processors;

public abstract AssetFile getBaseFile();

public abstract String getEncoding();

public abstract void setEncoding(String paramString);

public abstract void setBaseFile(AssetFile paramAssetFile);

public abstract InputStream getInputStream();

public abstract String getParentPath();

public abstract String getPath();

public abstract String getName();

public abstract AssetResolver getSourceResolver();

public abstract String processedStream(AssetCompiler paramAssetCompiler);

public abstract Pattern getDirectivePattern(); }

IMHO, because of the static fields are compiled final I cannot do something like this in my subclass:

class I18nAssetFile extends AbstractAssetFile { static String compiledExtension = 'js' static List contentType = [ 'application/javascript', 'application/x-javascript', 'text/javascript' ] static List extensions = ['i18n'] static List<Class> processors = [I18nProcessor] }

I also tried the following approach:

class I18nAssetFile extends AbstractAssetFile { static { AssetFile.@compiledExtension = 'js' AssetFile.@contentType = [ 'application/javascript', 'application/x-javascript', 'text/javascript' ] AssetFile.@processors = [I18nProcessor] AssetFile.@extensions = ['i18n'] }; }

But this doesn't work either. It seems, that the static initializer is not executed, because I get "processors is null".

Your help is really essential, because it prevents this plugin from working with version 2.0 of asset-pipeline.

— Reply to this email directly or view it on GitHub.

davydotcom commented 9 years ago

Figured this out ... finally ... If you use asset-pipeline 2.0.21 you should be fine. Don't put classes directly in the asset.pipeline package name, nest them so you don't mark the parent package as reloadable. This is actually a bug in spring-loaded where it inadvertantly marks the entire package as reloadable even though some of that package is in a non reloadable jar.

davydotcom commented 9 years ago

You should move your tag lib to package name asset.pipeline.grails or asset.pipeline.i18n

dellermann commented 9 years ago

Thanks for your help, David, now it works.