Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soy templates in native Graal images #32

Open
sgammon opened this issue Feb 13, 2020 · 4 comments
Open

Soy templates in native Graal images #32

sgammon opened this issue Feb 13, 2020 · 4 comments

Comments

@sgammon
Copy link
Contributor

sgammon commented Feb 13, 2020

I'm trying to use the Views layer, specifically with Soy, in a native GraalVM image. Although it works fine when executing on the JVM, the native-image tool seems to cull the compiled template code no matter what I do.

For instance, I've tried to embed JSON reflection configs, to no avail. I've tried statically referencing the template classes in a custom template loader, but it still elides them at runtime and produces a 404 (yielded by the Soy layer, not Micronaut itself).

I'm filing this as a placeholder so I can discuss possible fix approaches with the Micronaut team. Since we are already using the @View annotation, perhaps there is a way to either (1) generate static references to templates using DI, or (2) generate requisite JSON config entries to prevent templates from being rewritten.

This issue stems naturally from Soy's template loader's use of reflection to load template classes (see the use of Class.forName here). If this can't be solved within the Micronaut universe, there are alternatives - for instance, a code-generated template loader that relies on a compile-time plugin, rather than reflection.

@sgammon
Copy link
Contributor Author

sgammon commented Feb 13, 2020

@graemerocher I know this is at the nexus of two projects you don't control (Soy and Graal), in addition to Micronaut. But, being that you have worked with the tool so much, if you have any guidance about how I might fix this, I would love to push a fix or help work on one. Soy with Micronaut is a powerful layer, but without support for native-image we lock ourselves out of some awesome functionality.

@sgammon
Copy link
Contributor Author

sgammon commented Feb 13, 2020

okay, i've got a working static sample locally. basically, i just need to generate the following JSON using whatever tool micronaut already uses for controllers:

[
  {
    "name" : "template.class.Here",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
  },
  {
    "name" : "template.class.Here$Factory",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
  }
]

@graemerocher
Copy link
Contributor

I thought Soy didn't use reflection? If so than only allDeclaredConstructors would be needed. It may be worth writing compile time integration to generate this configuration. For example https://github.com/micronaut-projects/micronaut-core/blob/1.3.x/graal/src/main/java/io/micronaut/graal/reflect/GraalTypeElementVisitor.java

@sgammon
Copy link
Contributor Author

sgammon commented Feb 14, 2020

@graemerocher it only uses reflection once, to load a Factory embedded class from each template. the Class.forName itself isn't technically reflection, just dynamic class loading.

if using the old Soy runtime (SoyTofu), it interprets templates on the fly. apparently with SoySauce, the new runtime, it loads bytecode-precompiled templates via Class.forName, translated from a template path.

i'll give it a try with allDeclaredConstructors, and thank you for the useful link :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants