How build Vaadin project with gradle? - vaadin

I have gradle project (backend) and I want to add Vaadin-based frontend. But I haven't find any gradle-plugins for Vaadin.

While, as was already mentioned above, Vaadin app is a simple web application and does not require any additional plugins but "java" and "war" (and maybe "jetty" to run the app), currently there seems to be the first vaadin-specific gradle plugin available:
https://github.com/johndevs/gradle-vaadin-plugin
It will help you with Vaadin-specific task like building widgetsets, creating components skeletons, etc.

I think there is no a Vaadin plugin for Gradle but I have used Gradle in one of my Vaadin add-on projects: SplitButton. It's a project with sub-projects, widgetset compilation and it writes necessary jar manifest entries neebed by Vaadin Directory.
EDIT
Actually there is Gradle Vaadin plugin now - it allows you to easily build Vaadin projects with Gradle. It helps with the most tedious tasks when building a Vaadin project like building the widgetset and running development mode. It also helps you to quickly get started by providing tasks for project, component and theme creation:
https://github.com/johndevs/gradle-vaadin-plugin

You don't need a Vaadin plugin. A Vaadin application is simply a web application.The war plugin will suffice. If you want support for automatically creating the folder layout that Vaadin wants however, you might look into using the vaadin eclipse plugin found here:
http://vaadin.com/eclipse
If you are looking for deployment support, you can simply use the jetty plugin that comes with gradle or the tomcat plugin found here
https://github.com/bmuschko/gradle-tomcat-plugin
If you need to create custom widgets and compile them into a widgetset that's a GWT compile
https://vaadin.com/book/vaadin6/-/page/gwt.development.html#gwt.development.compiler
Note: The Vaadin7 Book no longer has the section on developing Gwt widgets.
There is a gradle plugin for GWT that could help with that. However, I've not needed a custom widget yet, so I haven't actually tried it.
https://github.com/markuskobler/gwt-gradle-plugin

This post:
Using Gradle with Vaadin
looks very comprehensive as far as Gradle+Vaadin setup goes. I'm also including a link to another Vaadin-based 'build.gradle' file I found on my travels, using Google's very useful 'filetype' search (see also the associated gradle.properties file).
JFYI that Google file search is:
filetype:<extension> <your search phrases>
Gradle can also be used to configure Eclipse and IntelliJ's project files by using a fragment such as the following (Eclipse natures can be 'found' by using the above Google file search for "project" extension and "natures" search, etc.):
//Template plugin - Great for project-layout setup - See http://tellurianring.com/wiki/gradle/templates
apply from: 'http://launchpad.net/gradle-templates/trunk/latest/+download/apply.groovy'
apply plugin: 'eclipse'
apply plugin: 'idea'
// if you want to distribute the gradle with your code
task('wrapper', type: Wrapper).configure {
gradleVersion = '1.0-milestone-8a'
}
def versionCompatibility = 1.6
//configurations.providedDependencies.extendsFrom configurations.gwt
eclipse {
project {
comment = ""
buildCommand "org.eclipse.jdt.core.javabuilder"
buildCommand "org.eclipse.wst.jsdt.core.javascriptValidator"
buildCommand "org.eclipse.wst.common.project.facet.core.builder"
buildCommand "org.eclipse.wst.validation.validationbuilder"
buildCommand "com.vaadin.integration.eclipse.widgetsetBuilder"
//buildCommand "org.eclipse.m2e.core.maven2Builder"
//buildCommand "org.maven.ide.eclipse.maven2Builder"
//buildCommand "com.google.gdt.eclipse.core.webAppProjectValidator"
//buildCommand "com.google.gwt.eclipse.core.gwtProjectValidator"
//buildCommand "com.google.gdt.eclipse.designer.GWTBuilder"
//Don't forget commas - no trailing
natures "org.eclipse.jdt.core.javanature",
"com.vaadin.integration.eclipse.widgetsetNature",
"org.eclipse.wst.jsdt.core.jsNature",
"org.eclipse.wst.common.project.facet.core.nature",
"org.eclipse.wst.common.modulecore.ModuleCoreNature",
"org.eclipse.jem.workbench.JavaEMFNature"
//"org.eclipse.m2e.core.maven2Nature",
//"org.maven.ide.eclipse.maven2Nature",
//"com.google.gwt.eclipse.core.gwtNature"
//"com.google.gdt.eclipse.designer.GWTNature",
//"ch.epfl.lamp.sdt.core.scalanature",
//"com.springsource.sts.grails.core.nature",
//"org.eclipse.jdt.groovy.core.groovyNature"
}
classpath {
containers "com.google.gwt.eclipse.core.GWT_CONTAINER"
//"com.springsource.sts.gradle.classpathcontainer"
//minusConfigurations=[configurations.gwt]
}
}
idea {
project {
jdkName = versionCompatibility
ipr {
withXml { provider ->
def node = provider.asNode()
// Set Gradle home
def gradleSettings = node.appendNode('component', [name: 'GradleSettings'])
gradleSettings.appendNode('option', [name: 'SDK_HOME', value: gradle.gradleHomeDir])
}
}
}
}
Cheers
Rich

Related

Electron plugin architecture, inject plugin code into the application

As the title say, I am trying to develop a plugin architecture for an electron app.
So far I have handle my custom plugin store the download of the plugin source which consist of an single main.js and a style.css.
I am stuck now since I don't know how to "require" the file from my application.
A little more explanation on this main.js file:
I want to require that main.js file to that I can retrieve the exported class to create a new instance in my PluginManager system.
It would be like so:
// plugin-manager.ts
loadPlugin(pluginId: string) {
const pluginClass = await import(path.join('/somewhere-in-the-fs', pluginId));
const plugin = new PluginClass({ app: myApp });
this.enabledPlugins.push(plugin);
}
tldr: I'm stuck at the await import() part because obviously my plugin is not in my running node environment.

URL in CSS no longer works in Vaadin 14.6

After upgrading from Vaadin 14.5 to 14.6 I'm facing problems with CSS that contains URL's that point to content.
For example, the following CSS no longer works:
:host([part="my-part"]) [part="reveal-button"]::before {
content: url("../images/my-image.svg");
}
It fails to "compile" when running the build-frontend goal of the Vaadin Maven plugin with the following error:
ERROR in ../node_modules/#vaadin/flow-frontend/styles/components/my-component.css
Module build failed (from ../node_modules/css-loader/dist/cjs.js):
Error: Can't resolve '../images/my-image.svg' in '<Project Path>\node_modules\#vaadin\flow-frontend\styles\components'
The same error appears in the browser if I try to run the project. This CSS has worked fine in all previous versions of Vaadin 14.
Has anyone encountered anything similar, or have any ideas as to what has changed that might cause this?
With the new custom theme feature the .css loader has changed from raw-loader to css-loader but it shouldn't touch urls outside of frontend/themes/[theme-name] or node_modules
Is the styles/components/my-component.css located in src/main/resources/META-INF/frontend, src/main/resources/META-INF/resources/frontend or src/main/resources/META-INF/resources to be packaged as an add-on jar or compatibility mode?
As in that case the css would end up inside node_modules which might make a difference to the resolving.
As a workaround if you are not building an add-on you should be able to move the css and image to {project_root}/frontend and it should build fine.
Until release of 14.6.2 you can add the raw-loader dependency to a java class with
#NpmPackage(value = "raw-loader", version = "3.1.0")
and then add to webpack.config.js the lines
if(flowDefaults.module.rules[2].test.toString().includes('.css')) {
flowDefaults.module.rules[2].use = [ {loader: 'raw-loader' }];
} else if(flowDefaults.module.rules[1].test.toString().includes('.css')) {
flowDefaults.module.rules[1].use = [ {loader: 'raw-loader' }];
}
Did you change the css structure to follow the new theme structure introduced in 14.6? It is not needed, but it is important context. I think it is at least related to your issue.
The path seems a little weird in your error messages, ending up in a node_modules folder. Could you share where this file is in, and what loads the file to your project?
With the new theme structure, I've used the following css to import images in css:
background: url('./images/fire.png');
And that was placed in a file: frontend/themes/mythemename/mythemefile.css

Importing external domain classes into Grails

I'm trying to create a sample project where domain classes are in an external normal groovy project and then used in a grails app (see https://github.com/ivanarrizabalaga/grails-domain-griffon):
book-svr
book-common
I'm also following the grails guide in order to get this (see http://grails.org/doc/latest/guide/hibernate.html) but the imported classes are not being recognized as domain classes.
The relevant parts:
External domain class:
package com.nortia.book
import grails.persistence.Entity
#Entity
class Book implements Serializable{
private static final long serialVersionUID = 1L;
String title
String author
static constraints = {
title blank:false
author blank:false
}
}
build.gradle:
....
dependencies {
// We use the latest groovy 2.x version for building this library
compile 'org.codehaus.groovy:groovy:2.1.7'
compile "org.grails:grails-datastore-gorm-hibernate4:3.0.0.RELEASE"
compile "org.grails:grails-spring:2.3.7"
....
In the grails app,
hibernate.cfg.xml:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
'-//Hibernate/Hibernate Configuration DTD 3.0//EN'
'http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd'>
<hibernate-configuration>
<session-factory>
<mapping package='com.nortia.book' />
<mapping class='com.nortia.book.Book' />
</session-factory>
</hibernate-configuration>
BookController.groovy (I've tried an scaffolded and coded controller, and both failed):
...
class BookController{
static scaffold=Book
}
...
console.log (error):
ERROR ScaffoldingGrailsPlugin - Cannot generate controller logic for scaffolded class class com.nortia.book.Book. It is not a domain class!
Finally, suspicious log messages while initializing:
DEBUG cfg.Configuration - session-factory config [null] named package [com.nortia.book] for mapping
INFO cfg.Configuration - Mapping package com.nortia.book
WARN cfg.AnnotationBinder - Package not found or wo package-info.java: com.nortia.book
DEBUG cfg.Configuration - session-factory config [null] named class [com.nortia.book.Book] for mapping
INFO cfg.Configuration - Configured SessionFactory: null
So I'm wondering:
What's the missing piece?
According to the docs, looks like external 'domains' must be java classes but that's not a good option for my purpose.
I haven't try yet with a grails binary plugin instead of a groovy project, is it the way to go? (I need to use the domains in a griffon project that is why I opted this way first).
Finally solve it creating a 'sort of' a binary plugin manually.
Let's take a look step by step:
book-domain
Tree structure
src
main
groovy
demo
Book.groovy
resources
META-INF
grails-plugin.xml
build.gradle
Book.groovy
package demo
import grails.persistence.Entity
#Entity
class Book{
String title
static constraints = {
title blank: false
}
}
grails-plugin.xml
<plugin name='book-domain' version='1.0' grailsVersion='2.3 > *'>
<author>Ivan Arrizabalaga</author>
<title>External domains</title>
<description>An external domain plugin</description>
<documentation>http://grails.org/plugin/book-domain</documentation>
<type>demo.BookDomainGrailsPlugin</type>
<packaging>binary</packaging>
<resources>
<resource>demo.Book</resource>
</resources>
</plugin>
build.gradle
/*
* This build file was auto generated by running the Gradle 'init' task
* by 'arrizabalaga' at '5/26/14 12:34 PM' with Gradle 1.11
*
* This generated file contains a sample Groovy project to get you started.
* For more details take a look at the Groovy Quickstart chapter in the Gradle
* user guide available at http://gradle.org/docs/1.11/userguide/tutorial_groovy_projects.html
*/
// Apply the groovy plugin to add support for Groovy
apply plugin: 'groovy'
apply plugin: 'maven'
group = 'demo'
version = '1.0'
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'maven central' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
mavenCentral()
mavenLocal()
}
// In this section you declare the dependencies for your production and test code
dependencies {
// We use the latest groovy 2.x version for building this library
compile 'org.codehaus.groovy:groovy-all:2.1.9'
//compile "org.grails:grails-datastore-gorm-hibernate4:3.1.0.RELEASE"
compile "org.grails:grails-datastore-gorm-hibernate:3.1.0.RELEASE"
compile "commons-lang:commons-lang:2.6"
// We use the awesome Spock testing and specification framework
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile 'junit:junit:4.11'
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
using it
Now the project can be built (gradle install to publish it into your local maven repo) and used (declaring the proper dependency) in any given project.
If the project that uses the jar is a Grails app it turns automatically the #Entity classes into real Domains.
Hope it helps.

Is there a way to inherit BuildConfig from a set of plugins to the current application?

Is there a 'builtin' way to share BuildConfig from plugins to a host application?
We have an application that is using homemade plugins and we need to copy/paste all special configuration (so everyting but dependency) settings from plugins to current app.
This is quite awful and it brings maintenance issue: when plugin A change its config, we need to update all project using this config.
I would like to be able to re-use as much as possible of the build settings from the plugin and just add specific settings (or replacement settings) to the main project BuildConfig.
The kind of properties we would like to share are:
common grails config block like:
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.target.level = 1.6
grails.project.source.level = 1.6
specific plugin config:
grails.project.myplugin.config = { specials things }
some commons properties like dependencies version
In fact we want to have a kind of inheritance in the builconfig, a bit like when you define a parent project in a maven pom file.
In you're MyAppGrailsPlugin.groovy, you need to add a merge config function:
def doWithSpring = {
mergeConfig(application)
}
private void mergeConfig(GrailsApplication app) {
ConfigObject currentConfig = app.config.grails.fooConfig
ConfigSlurper slurper = new ConfigSlurper(Environment.getCurrent().getName());
ConfigObject secondaryConfig = slurper.parse(app.classLoader.loadClass("FooConfig"))
ConfigObject config = new ConfigObject();
config.putAll(secondaryConfig.fooConfig.merge(currentConfig))
app.config.grails.fooConfig = config;
}
def onConfigChange = { event ->
this.mergeConfig(application)
}
reference: http://swestfall.blogspot.ca/2011/08/grails-plugins-and-default-configs.html
I don't think you could merge the settings in plugin's BuildConfig to app's BuildConfig, because it will not be available in classpath to copy yet.
Moreover, your "special settings" (if they are not related to build) should be externalized and go to plugin specific *Config.groovy which can be easily amalgamated to host app by using the below in host app's Config.groovy:
grails.config.locations = ["classpath:${pluginSpecific}-config.groovy"]
Refer Externalized Configuration for details and Plugin Config plugin for more.
On the other hand, when behavior like parent object in maven pom is concerned, the approach to manipulate host app's build process from plugin is kind of scary. This has to be driven by host's build configuration and host can be idempotent about plugin's behavior.

Grails Jquery-ui plugin configuration

Trying to use the Jquery-UI plugin from http://grails.org/plugin/jquery-ui
but apparently the documentations is not correct when discuss using the plugin with resources framework as following the instructions leads to an error:
Error processing GroovyPageView: Error executing tag <r:layoutResources>: No module found with name [jquery-ui]
Apparently the same problem is known around, but was not able to find a solution on the net (example: some discussion here and some other discussions with no solution or hints to a solution).
Did anyone managed to successfully configure jquery-ui in grails with the resource framework?
First you need to install the plugin, so in your BuildConfig.groovy
plugins {
...
compile ":jquery-ui:1.8.24"
...
}
Use grails compile --refresh-dependencies and see if the console output the download of the plugin. If you are using STS, you can go in right click > grails tools > refresh dependencies
After that, you can add <r:require module="jquery-ui"/> before the <r:layoutResources/>
A usefull tip is the change of the jquery ui theme, you can configure this in your ApplicationResources.groovy
modules = {
overrides {
'jquery-theme' {
resource id:'theme', url:'/css/ui/jquery-ui-1.8.21.custom.css'
}
}
}
In this example i have one css located in web-app/css/ui/.
Another tip is that you can force your modules to depend on jquery-ui:
modules = {
mymodule {
dependsOn 'jquery-ui'
resource url: '/js/my.js'
}
}
So if you add the resource mymodule to your GSP, the jquery-ui will be loaded too.

Resources