How to automate GWT builds using different sets of property values? - java

I need to be able to build two different versions of my GWT application using two different sets of property values. For example, one version would be built with the value of custom_property set to "A" and another would be built with the value of custom_property set to "B".
Currently I am editing the application's module XML file in between builds by hand. So, to make one build I would first add:
<set-property name="custom_property" value="A"/>
And to make the other build I would change this line to:
<set-property name="custom_property" value="B"/>
This approach is working okay, but I would like to automate it if possible.
Is there a good way to accomplish this?

One powerful way to do this would be using Maven substitution. I've used this approach in many GWT- and non-GWT-based apps. Due to Maven's prevalence, you'll find loads of examples of Mavenizing your GWT app. Then you can use Maven substitution to make all the magic happen.

You can clone your app's module XML file and change values of your custom properties in it (e.g. MyAppStaging.gwt.xml and MyAppProd.gwt.xml). You'll thus be able to script builds of different app versions and have different run configurations in your IDE. The drawback here is in subsequently needing to maintain both module XML files.

Building on #BorisBrudnoy's idea of multiple module XML files, I placed all module XML that was not related to setting the properties that differ between builds in a MyAppBase.gwt.xml file. I then created MyAppA.gwt.xml with:
<module rename-to="myappA">
<inherits name="com.mycompany.MyAppBase"/>
<set-property name="custom_property" value="A"/>
</module>
and MyAppB.gwt.xml with:
<module rename-to="myappB">
<inherits name="com.mycompany.MyAppBase"/>
<set-property name="custom_property" value="B"/>
</module>
Now I can specify either com.mycompany.MyAppA or com.mycompany.MyAppB on the GWT compile command line, and there is no replication of configuration.

Related

Custom properties when creating maven archetype (archetype-metadata.xml)

I'm trying to create an archetype that I'll use for multiple services. The archetype generates a project just fine, all modules and files that I want included. Problem is, I'd like to set custom names for the modules and folders that the project has, depending on the service I'll be creating
Currently I have something like this (just an example):
<requiredProperties>
<requiredProperty key="testName"/>
</requiredProperties>
<module id="service-data" dir="service-data" name="service-data" />
What I'd like to happen is something like this:
<requiredProperties>
<requiredProperty key="testName"/>
</requiredProperties>
<module id="${testName}-data" dir="${testName}-data" name="${testName}-data" />
Basically, I'd like to give the archetype a parameter so that when I create a project using it, instead of service-data being my module name everytime, it ends up being say test-project (if testName = test).
I tried using the testName parameter as shown in this example, but what ends up happening is the module will literally be named ${testName}-data.
Using the requiredProperty works just fine for other pom.xml or other files in the project, but I'm really interested if I can set custom properties that will work directly in the archetype-metadata.xml file.
Thanks!

Choose one dependency as precedent over another for an arbitrary list of packages in the IntelliJ Builder

Goal
I'm trying to make my maven project use the IntelliJ builder when I'm editing code because the IDE offers fast rebuild and hot deployment features that could speed up my work. However I'm running into a roadblock due to how my maven project is set up.
Constraints
I have to use maven the way it's being used. The solution must be in IntelliJ
Note that creating an IntelliJ plugin is an option. I realize this may be necessary due to the limitations of IntelliJ build configuration.
The problem
My project depends on 2 libraries, SharedLibA and SharedLibB, which contain package com.shared. SharedLibA is a new library, and sharedLibB is and old legacy one. SharedLibA and SharedLibB contain packages that are not contained in the other, which are needed by my project. The package they both have, com.shared is needed by the project too. However SharedLibB is legacy/old so we always want Tomcat to prioritize the implementation of classes in com.shared from SharedLibA, not the implementations of those classes in SharedLibB. We accomplish this by having a maven goal that extracts classes under package com.shared from SharedLibA to WEB-INF/classes when the WAR is packaged.
When I try to build my project in IntelliJ, it picks up the wrong implementation of classes in com.shared.* and spews out compilation errors despite compilation working perfectly via maven. I'm stuck with this inflexible maven hackjob but I still want to find a way to make IntelliJ understand that I want SharedLibA's com.shared.* classes to be used in compilation not SharedLibB's. I can't remove SharedLibB from consideration because I need the other classes in SharedLibB to compile my project.
Desired Solution
I'm looking for some kind of logic like "when com.shared.* classes are considered, choose SharedLibA" or "when any package conflict happens in classpath resolution, prioritize ShareLibA" because I'm pretty sure SharedLibA should be prioritized in any package conflict.
Thanks
I hope that explains it well enough, thank you in advance to anyone who chimes in here.
IDE builds the classpath and buildpath based on the dependencies which are configured for the module. It also considers their order - the 1st dependency that match given class will be used.
For Maven-based projects the dependencies list and their order IDE takes from the Maven pom.xml file of the module. So you can set the order in pom.xml file.
Another mentioned option is to exclude the library items. But the better solution would be to configure Maven build properly.
You should try to go to your project ".IML" file and there :
you can create or modify a module.
In there you can include or exclude the libs or defining its use priority
you could use this snippet to inspire
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="8">
<component name="SharedB" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
...
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
...
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
...
</component>
</module>
if you are not confortable with this solution you could use the module settings of Intellij
https://www.jetbrains.com/help/idea/library.html#excluded_lib_items

Need in understanding classpath in resource location and variable value set

Although I have been working in java for a while, there are many small things I have been ignoring, which at times have become bottleneck in productivity. I have difficulty in understanding this:
This is one of the bean.xml which gets placed in the final .war file (in a web application, built with spring framework).
<context:property-placeholder
location="classpath:/${deploy.env}/com.example.config/db.properties"
ignore-resource-not-found="false" />
I have following doubts:
1) At the time of building the code, i did like this for passing value of deploy.env
mvn clean install -Ddeploy.env=local
I ran the mvn in debug mode and could see this set to local. Now, the thing is, in the .war that gets generated, it is still ${deploy.env} (see above snippet). Doesn't this get replaced in the final .war? If not, then how do we pass the value which we intend to set?
2) what does "classpath:/${deploy.env}/com.example.config/db.properties" mean? Who sets the value of classpath? Are classpath capable of providing the location of resource files as well?
Assuming deploy.set --> local, so would this get translated to:
classpath:"/local/com.example.config/db.properties"
So does this mean db.properties would be present at: /local/com.example.config/db.properties
Any inputs to understand this would be of great help.
deploy.env is either environment variable or system property available to the JVM at run time.
The classpath:/${deploy.env}/com.example.config/db.properties will be resolved at run when your war is running in the container.
Set deploy.env=whatever in the shell from where you starting the tomcat or set in the environment of the user which starts the tomcat.
mvn clean install -Ddeploy.env=local here the deploy.env system property is available at build time. This will not replace the value of your spring config.
classpath is where all your classes and libraries bundled in the war are available along with the tomcat libraries. The spring property configurer will look for the db.properties file in the classpath at location e.g. /local/com.example.config
Spring documentation to learn more
Some explanation on my blog post
As stated in the Oracle Web site: The CLASSPATH variable is one way to tell applications, including the JDK tools, where to look for user classes.
That classpath: is referring to that location in particular, whatever it is, so it will start looking for those resources defined by Spring from that location and on, until it finds the first match.
Also, if you have that as a property in Maven, the value can be replaced with the right plug-in and configuration; not quite useful when you want a build that can be used with many values within those .properties files for different environments.
You can use other prefixes as file:, http:, etcetera. But you are just wondering about classpath:.

Why GWT Linker Cross-Site-Iframe Ignoring the script tags in the gwt.xml?

Why gwt-recaptcha-1.0.0.Beta2.jar blocks script tags in recaptcha jar while linking modules?
In my web application using GWT, I am using captcha verification. For using captcha I used Claudius Hauptmann's gwt-recaptcha-1.0.0.Beta2.jar. In the gwt.xml file of this jar there is a script configuration as follows:
<module>
<inherits name="com.google.gwt.user.User"/>
<script src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"/>
</module>
When I run the project it ignores loading the scripts by giving these messages in console:
Linking modules
Bootstrap link for command-line module 'com.web.Ask'
Linking module 'ask'
Invoking Linker Cross-Site-Iframe
Ignoring the following script tags in the gwt.xml file
https://www.google.com/recaptcha/api/js/recaptcha_ajax.js
raphael.js
I would like to know what is the exact reason for ignoring these file. How to resolve it.
PS: before some days it was working perfectly and after some config changes it stopped.
I am not sure about this fix,
please try
Remove linker elements from your GWT module XML like
<add-linker name="xsiframe" />
<set-configuration-property name='xsiframe.failIfScriptTag' value='FALSE' />

How can share bean from external library to GWT client?

I have a question about share the java bean in library to gwt client
I know bean share between GWT client and server usually put into package domain.shared.
However, how can I make use of existing bean from external jar library on GWT client?
Because I always got this message.
No source code is available for type xxxx.xxxx.bean did you forget to inherit a required module?
Given that your beans are in the package xxx.xxx.bean, and they are in an imported my_beans.jar library.
Create a folder in your Application src tree (or src/main/java if you are using maven) with the name xxx/xxx
Create a new Module file in this folder called MyBeans.gwt.xml with this content:
<module>
<inherits name='com.google.gwt.user.User'/>
<source path="bean"/>
</module>
Edit your Application.gwt.xml and add this line
<inherits name="xxx.xxx.MyBeans"/>
Be aware that all Classes in the xxx.xxx.bean package must use classes supported by GWT.
You should check as well that the my_beans.jar library includes the java source files of the beans you are going to use.
1) You can only include beans from the external jar library provided it is GWT compatible and declares a <ThirdPartyModuleName>.gwt.xml file which includes the package for the beans you need to use.
2) You should have the <ThirdPartyModuleName> included in your own <Module>.gwt.xml using <inherits> tag.

Categories