Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Compiling, Running, Packaging and Debugging SGWT in Maven Project

    I've seen a couple of questions lately about how to compile, run and debug SGWT in Maven 'enabled' projects, so I'll try to explain my take on this, in case somebody is in a similar situation. Please take into consideration that SGWT's developer tools and Chrome developer console are also very useful when trying to debug your projects!

    So, first, here is a description of the technologies I'm using to develop my apps:
    1. SmartGWT 6.0p.
    2. GWT 2.7.0.
    3. Maven 3.3.9 (for dependency management, plugins for several build/deployment tasks, etc).
    4. m2eclipse 1.6.2 (Maven Eclipse plugin)
    5. JDK 1.8
    6. Glassfish 4.1 (to run my apps in both development and production - for development runs I create a GF4 server in my Eclipse workspace, to easily start it normally or in debug mode - later you'll see how this comes in handy). I haven't tried other servers, but I guess it must be very similar.
    7. Chrome 49.0.2623.112 m as my testing/debugging browser of choice.
    8. Eclipse Mars.2 (4.5.2)
    With that out of the way, the first step in my projects is to set my pom.xml. I'll omit the dependency declaration, to keep things to the point. I'll only show the <properties> (partially) and <build> (complete) portions, but if someone needs the full content, please feel free to ask:
    Code:
    <properties>
        <!-- Artifact versions -->
        <gwt.version>2.7.0</gwt.version>
    
        <!-- Maven GWT compiler version and parameters -->
        <maven.compiler.version>3.3</maven.compiler.version>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <compiler.style>OBF</compiler.style>
        <compiler.log.level>INFO</compiler.log.level>
        <glassfish.port>8082</glassfish.port>
        
        <!-- Maven War plugin version and parameters -->
        <war.plugin.version>2.6</war.plugin.version>
    
    </properties>
    <build>
    
        <!-- This will produce a war file named AppName.war, rather than
            AppName-${project.version}.war. This is my preference, but you can change it -->
        <finalName>AppName</finalName>
    
        <!-- Set classes 'output dir' matching the hosted webapp WEB-INF/classes
            folder, so GWT Hosted browser can see the classes. -->
        <directory>target</directory>
        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
    
        <plugins>
    
            <!-- Plugin to compile GWT Java code to JavaScript.
                 Usage: mvn gwt:compile (will compile GWT files to JavaScript) -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>gwt-maven-plugin</artifactId>
                <version>${gwt.version}</version>
    
                <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                                <goal>generateAsync</goal>
                                <goal>test</goal>
                            </goals>
                        </execution>
                </executions>
    
                <configuration>
        
                        <!-- Compiler parameters -->
                        <extraJvmArgs>-Xss1024K -Xmx1024M</extraJvmArgs>    
                        <draftCompile>true</draftCompile>
                        <debugSuspend>false</debugSuspend>
                        <logLevel>${compiler.log.level}</logLevel>
                        <style>${compiler.style}</style>
                        
                        <!-- Launch parameters with external server -->
                        <!-- Add the app to Glassfish embedded server and set the server to
                             publish automatically after each compile -->
                        <noServer>true</noServer>
                        <runTarget>http://localhost:${glassfish.port}/${project.build.finalName}/${project.build.finalName}.html</runTarget>
                        
                        <!-- Build parameters -->
                        <buildOutputDirectory>${project.build.outputDirectory}</buildOutputDirectory>
                        <hostedWebapp>${project.build.directory}/${project.build.finalName}</hostedWebapp>
                        <copyWebapp>true</copyWebapp>
    
                </configuration>
    
            </plugin>
    
            <!-- Plugin to compile the project. Included here only to specifically
                 define the source and target versions of the project. If you don't include
                 it, Maven will do it for you (in the Effective POM).
                 Usage: mvn compile (will compile java files to classes) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                        <source>${maven.compiler.source}</source>
                        <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
    
               <!-- Plugin to package in war file. It assumes that the project
                 is already compiled, so you need to compile GWT and java code before.
                 Usage: mvn war:war (packages files and resources in war file)
                 Suggested usage: mvn clean compile gwt:compile war:war -->
               <plugin>            
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>${war.plugin.version}</version>
                <configuration>
                    <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
                    <!-- Exclude what you want from the final artifact here -->
                    <!-- <warSourceExcludes>.gwt-tmp/**</warSourceExcludes> -->
                </configuration>
            </plugin>
            
        </plugins>
    </build>
    Now, to compile, run, package, clean and upgrade your project, you can add the following Run Configurations of the type Maven Build:
    • For cleaning, just create a run config with the goal clean. Make sure to properly configure the Base Directory (${workspace_loc:/AppName}). I use this run config to clean my project every time I make changes to the technologies used in the project (like for instance, every time I upgrade to a new SGWT version).
    • For compiling, create a run configuration with the goal gwt:compile. This is normally done before a packaging operation (but as you'll see later, even then it is needless to execute this config individually). Otherwise, I don't just compile the app, but use the run config (keep reading).
    • For running your app in the external server defined in the pom.xml (Glassfish in my case) in Super Dev Mode, just use the goal gwt:run. This will start the code server, required for the app to run and for you to be able to debug your code. This is the config I use all the time, since it compiles the code (if needed) and starts Super Dev Mode, so that I can start running and debugging my app. When you use this config, you will get a new window with some logs related to the code server and some options to launch the app in your web browser.
    • Finally, when you are ready to deploy, run clean compile gwt:compile war:war. This will create a war file in the target directory (as configured above in the pom, in the <directory> property. As you can see, the goal includes clean and compile, so that you don't need to remember to run those goals before starting to package the app.
    • Using another run config, I get the latest SGWT version from Isomorphic's repository into my local repo, ready to be used in my pom dependencies. For this I run this maven goal: com.isomorphic:isc-maven-plugin:install -Dproduct=SMARTGWT -Dlicense=PRO -DbuildNumber=6.0p -DbuildDate=2016-04-12, changing the build (DbuildNumber) and type of license (Dlicense) according to my needs. Note that for this to work you need to configure your credentials in Maven's application.xml. See my post in this thread for further information on how to do this.
    Moving to the debugging part: in order to debug your server classes (servlets, filters, etc), you will then use the debug mode of your server. This will allow you to set break points, step through your code, etc, as you are probably used to. Remember to use the debug mode, and not the regular run mode! This is the button I hit to start debugging my server code (in case you are wondering, note that this is not the same as debugging SGWT server classes). So, in order to start debugging server code you will need to:
    1. You probably want to set your server to publish any changes in your workspace automatically, so that each time you save project changes, they are automatically deployed to the server and available for your to run/test. For this, double click the server name (as shown in the image below) and go to the Publish tab to set your preferences. I use the 'automatically publish after a build event', and set the publishing interval to a very low value (0 to 5 secs). Play with this config and see what works best for you. (This step needs to be performed just one time, when setting up your environment).
    2. Start GF in debug mode. Your files will be deployed to the server.
    3. Use the config discussed above for running your code server and launching the app in the preferred browser. Depending on how your app is built, when it opens in the browser a new compilation process will start automatically. If it doesn't, hit refresh in your browser to trigger it. At the end, all new and updated files will be published to the server (depending on what you defined in step 1).
    4. After the compilation and publishing processes are done, and you are able to use your app, set some break points.
    5. When hit, step through your code as needed (F5, F6, etc).
    Click image for larger version

Name:	RunGFEclipse.png
Views:	457
Size:	6.0 KB
ID:	237006

    And in order to debug your client side code, just use SDBG. You can get it here. And you can see how it is used in that same link, in a short video on top of the page. Some notes about this:
    1. You need to create a 'Launch Chrome' debug configuration (this is a new option added to the debug configurations window when you install SDBG). If you make it a run config, it won't let you debug your code. Follow the instructions on the video to accomplish this!
    2. Start glassfish (or your server) in debug or run mode (I usually start it in debug mode anyway, so that I can both debug server and client side code during the same session). Having your server configured to automatically publish your changes is important here as well (see step 1 of the server side debugging steps).
    3. Run GWT's code server using the config discussed above.
    4. Run the 'Launch Chrome' config from step 1. A new Chrome window will open, and Eclipse will be ready to start debugging client side code.
    5. Add break points as desired (in v1.0.8 there is a bug that in some situations prevents SDBG to hit breakpoints set in the onModuleLoad method). See this for more information. Otherwise, it works beautifully.
    6. When hit, step through your code as needed (F5, F6, etc).
    Well, hopefully I covered everything I know regarding theses topics...
    Last edited by carlossierra; 15 Apr 2016, 06:43. Reason: Added Eclipse to the list of technologies used
Working...
X