David J McClelland

Experiences at the Intersection of Programming & Design

Archive for the ‘Tools’ Category

What is a “Thing” in Thingworx Composer?

thingworx-ptc-logo

What is  a “Thing”?

A Thing is defined by Thingworx as a representation of a business process in terms of properties and business logic. For example, a locomotive would be represented not in terms of static information such as dimensions, color and weight but in terms of dynamic business-relevant such as its current location, pulling capacity and maintenance status.

What Makes Things Interesting?

Things are only interesting if they have characteristics that interest us. To extend the locomotive analogy, a train that is running on time and about to reach my station is probably more interesting than one still an hour away. It is even more interesting if it is going to my destination. These characteristics are called Properties in Thingworx.

How Do Things Talk?

A train is famous for blowing it’s horn or whistle. The interest level of a train whistle’s can vary by distance or whether you are waiting for a train or standing on the tracks. But there is no indication in a whistle that indicates which train the whistle comes from or necessarily why it was blown. Things address these limitations by providing a rich system of events, alerts and subscriptions.

Events: When Things Happen To Things

A Thing Property can have an Event defined. This is a business rule where an action can be taken when a property changes in a certain way. Such as a train that is more than 5 minutes behind schedule.

Alerts: We Care When Certain Things Happens

Events can trigger a message to the next station which could display an updated arrival time on a schedule display. They can also be used (along with additional rules and location data) to calculate what speed increase is required to catch up before arriving at the next station and supress sending a late arrival message.

Subscriptions: Only Some of Us Care

Telling a system what alerts are wanted ensures that only information of interest is sent. Instead of standing by the train arrival display, commuters use an app to subscribe to updated arrival times so they can sit in the coffee shop and wait for a jingle when they have a couple minutes left to board. This requires subscribing to alerts for your train at your planned departure time.

When to use:

  • Where a specific representation of an instance of an asset that combines properties, processes and business logic is needed.
  • Things are also often used to provide a single instance of internal application services, such as a utility function holder.

A Thing Example

Thingworx Thing Icon

A Thing is represented by this default icon in the Composer Editor Home Menu. The most basic Thing is one based on GenericThing. This is as basic a Thing as you can define. It inherits the properties and services that are required for any Thing, much like an interface would define required properties and methods of a Class.

thingDetails4

Extending a Thing

Things are only useful when you define specific properties, services, alerts and alarms on them. You can do this using built-in capabilities inherited from the Generic Thing.

To clearly illustrate how the these features interact to provide functionality I will show how to exercise all aspects of a Thing using only custom features:

  • Create a Thing Property
  • Create a Thing Service
  • Create a Service Event
  • Create a Thing Subscription
  • Integrate a Thing into a Mashup

Custom Property

To add a custom property to a Thing, create a new Thing that inherits Generic Thing. Click the Properties link from the Left menu. Refer to the screen shot below. We will add a boolean property because it is a simple switch.

Thing Custom Property

Thing Custom Property

Thing Service

A Service is an implementation of a rule in a Thing that can manipulate data. Rules are written in Javascript by default. See the screenshot for how to program a service that switches an input boolean value to the opposite of its current value. The data can come from a Thing property.

Thing Service

Thing Service

Subscriptions

Subscriptions are used to respond to particular events. In this example I subscribe to an data change event on my Thing when the property value is flipped to false.

Thing Subscription

Thing Subscription

Using a Thing in a Mashup

There isn’t a “Thing Widget” that can be dragged onto a layout in Thingworx Composer. Specific aspects of a Thing can be added to a Mashup via a combination of widgets and data services. This can add up to a selective rendition of the aspects of a thing that focuses on the aspects of it that are important for a particular viewer.

How Thing Appears in Mashup

How Thing Appears in Mashup

Wiring Mashup Events

Wiring Mashup Events

Using data to set Widget

Using data to set Widget

Setting Alerts

Alerts can be added to each property of a Thing. They can be set to fire when a condition is met. In this case, when macProperty is false.

Add Alerts to Properties

Add Alerts to Properties

Alerts Manager

Alerts Manager

Viewing Alerts

Alerts can be subscribed to in order to set other properties, send emails, SMS, and other communications. The following screens show the event Monitor tab recording the alerts fired when macProperty was set to false by clicking the checkbox in the Mashup.

An Alert Displayed in the Alert Monitor

An Alert Displayed in the Alert Monitor

An Unacknowledged Alert

An Unacknowledged Alert

No Acknowledged Alert Yet

No Acknowledged Alert Yet

alertsTabAcknowledge

Acknowledge The Alert

Alert Acknowledgement Confirmed

Alert Acknowledgement Confirmed

Acknowledged Alert

Acknowledged Alert

New Alert

A New Alert

Alert History

Alert History

  • 0 Comments
  • Filed under: Tools
  • Intellij IdeaCygWingitorange@2x

    I didn’t find much existing basic documentation on how to get started with scripting in earnest, so I decided to fill the gap with my own experience. I had never been an avid user of command windows or terminals or scripting, and I admit to complaining that Cygwin is be a confusing heap. But that hasn’t stopped me from realizing their benefits, and I am ready to give them the respect they deserve since they have saved me time and drudgery.

    Solving Script Amnesia

    A successful script automates some tedious activity on the OS and is soon forgotten. That’s my problem: when I need to write or edit a script its hard to pick up where I left off or remember arcane syntax that I don’t use anywhere else. I don’t write scripts all day, so I often don’t remember where I put it, what environment I edited in, let alone some arcane syntax and other context information.

    I should have realized a long time ago that if a script is worth writing, it is worth safeguarding and properly maintaining like any source code. But script editing happens in spurts as a means to an end – it’s hard to justify taking the time to build up an infrastructure and become more proficient. This post documents how I set up a script repository and IDE using Git, Bitbucket, IntelliJ, Cygwin and some assorted environmental variables. So this documents my effort to get a a scripting environment set up that I can get familiar with and rely on. I’ll know it’s successful if I start writing more scripts because I feel more confident that I will get a longer return from the effort.

    Before I set up my scripting environment I asked my self some questions to help determine what tools and techniques I would need, and I encourage you to do answer these as well:

    Scripting Environment Questions:

    • Portability: How portable does my script need to be?
      • What OS(s) will it run on? My case: Win/Mac/Linux
      • What user(s) will use it? Me/Coworkers/My boss/Continuous Integration
    • IDE? Can I edit my scripts in the same IDE I use for everything else? Yes (detailed follow)
    • Extensibility: If my script can’t do everything natively, is there a strategy to add functionality? (Yes, details follow)
      • For example, if your script needs to do a REST call, do you: script a browser? import a cURL library?
    • Conventions: Is there a convention I can follow to put my scripts where both the OS and I can find them without tweaking? (Yes, requires some care)
      • For example: home/user/bin

    My answers lead me to a create a setup that prioritizes flexibility across OS and users and tries to follow general conventions. So, it should work for anybody, but you can sacrifice some of the generalization for your own convenience if you want to.

    Portability

    Once you combine Windows with another OS you are probably going to run into Cygwin as your go-to solution because you can write bash scripts that can run on Windows, MacOS and Linux. It is still very possible/maybe necessary to write Windows-only scripts in Cygwin. All my scripts are .sh except some narrow Windows cases.

    Portability also pertains to editing and running scripts on multiple machines in multiple user accounts. It means creating a project definition that can be put under version control to allow me to edit and run scripts on any machine as any user. To do this I followed conventions regarding where to house scripts (see Conventions below) and set my cygwin user folder as the project root and committed this to BitBucket using Git.

    IDE Support

    Maybe it should have been obvious, but it took me awhile to decide that I should strive to use my regular editor to edit scripts. I use IntelliJ, and I found a plugin called BashSupport that supports syntax highlighting, rename refactoring, documentation lookup, inspections, quickfixes and such. I can also run scripts from run configurations within IntelliJ- not sure if that is due to BashSupport or not honestly. Before that I used Notepad++, or simply Notepad. Another big advantage of using an IDE: it creates a project definition so you can reopen the project and see your scripts! Again, should have thought of this earlier, but my scripts were all small and scattered and this seemed like a heavyweight tank cracking a nut.

    Extensibility

    Cygwin has cultivated a large library of plugins that scratch the itch of various developer needs. It is likely to cover any requirement I will have. Install Cygwin to C:\ and don’t install any optional components. Save the installer (setup-x86_64.exe in my case) in the cygwin folder inside a folder you create called installer. Cygwin will create a cache of the plugins library in there. You will need the installer if you ever decide to install a plugin, so its a good idea to keep it with the project folder instead of losing in in the downloads folder like I have done.

    cygwinAlwaysRunAsAdmin

    Tip: In Cygwin Shortcut select Preferences: Shortcut Pane: Click Run as Administrator

    Conventions

    Cygwin tries to follow conventions whenever possible. It puts a directory structure that mimics Linux root, but it is located inside the Cygwin installation folder. Instead of accepting the default “Program files” location, install cygwin at C:\ to avoid spaces in any paths. My user dir is therefore: C:\cygwin64\home\[windows username]\bin. I added bin to .bashrc so I can run scripts from anywhere in Cygwin.

    Running Scripts

    From Intellij: As I mentioned, you can run shell scripts from within Intellij using run configurations. This seems like a lot of work after getting past the cool idea factor. It doesn’t open up any debugging options as far as I can tell. It’s a good idea to check the “Show this page” box to fill in any necessary arguments before running a script.

    cygwinRunConfiguration

    Intellij Script Run Configuration

    scriptRunInIDE

    Script output in Run Output of Intellij

    From Cygwin: cd bin, then ./script.sh to execute. Or add bin to .bashrc and execute script.sh from any location. Add Cygwin to context menu in Windows.

    From Git Bash: Open it from your bin directory to run a script on a Windows dev box lacking Cygwin. Otherwise useless because it is not extensible and conventional.

    You can run Cygwin in the IntelliJ terminal or in a terminal emulator like Conemu as well – Google for details.

    Polymer Data Models/Templates in Custom Elements

    A custom element can contain it’s own data source and be its own data model, as this example shows. The script provides a JavaScript object “salutations” containing a list of 4 objects with properties “what” and “who”.

    The inner template sets a repeat property that processes each “who/what” object “s” in salutations. The contents of the template is a mix of html and mustachioed object notations that results in a repeater containing labels and text inputs as shown in the inset from the resulting page.

    Source Code Explainer

    customElementDataModelTemplate

    My Feature Branch

    Polymer.org Example

    Live example

  • 0 Comments
  • Filed under: Practice, Tools
  • How to Add a Custom Element to a Polymer Project

    polymerLogo

    Starting with a project build with Yeoman (Yo Polymer), I add a custom element and display it in the index file. In addition, how to set up a project to build with Vulcanize and why, and how custom elements relate to the data model in Polymer is discussed.

    polymerSandboxDirectory

    polymerSandbox with djm-nameTag element

    I made a copy of one of the existing custom elements in the Yo-Polymer base project. I replaced the contents with a nametag example element from the Polymer data binding topic on their website. I named it with djm- prefix in order to satisfy the Polymer requirement that custom element names contain a dash while also adding a namespace to it by referring to my initials.

    djm_nameTag

    <link rel="import" href="../../bower_components/polymer/polymer.html">
    
    <polymer-element name="djm-nameTag" attributes="">
    
      <template>
        This is <b>{{owner}}</b>'s djm-nameTag element.
      </template>
    
      <script>
        Polymer('djm-nameTag', {
          // initialize the element's model
          ready: function() {
            this.owner = 'Rafael';
          }
        });
      </script>
    </polymer-element>

    Then I added the element to the index.html file body.

    <djm-nameTag></djm-nameTag>

    I expected to have to add an html import to the index file but there were no imports for the other elements. I realized that they were being imported via the vulcanize library method.

    <!-- build:vulcanized elements/elements.vulcanized.html -->
    <link rel="import" href="elements/elements.html">

    I added a djm-nameTag entry to elements.html

    Then when I ran

    grunt build

    grunt cleaned and rebuilt the dist directory and added djm-nameTag element to the elements.vulcanized.html file.

    polymerSandboxDistDirectory

    polymerSandbox dist directory including elements.vulcanized.html

     

  • 0 Comments
  • Filed under: Techniques, Tools
  • Building a Polymer Project From Scratch

     

     nodeJs + npmLogo + bower + yo + gruntLogo =polymerLogo

    1. Download and install NodeJs
    2. Make sure nodeJs is on the system PATH.
    3. Open a command window and enter node -v
    4. Install Node Package Manager (NPM): Enter npm install npm -g
    5. npm install -g grunt-cli
    6. npm install -g bower
    7. npm install -g yo
    8. npm install -g generator-polymer
    9. Create a project directory and navigate inside it from command: mkdir my-new-project cd $_
    10. To build a polymer skeleton project: yo polymer

    More on yo polymer scaffolding generator

    yoPolymerDirectory

    Scaffolded Polymer Project Directory after yo polymer

     

    yoPolymerDirectoryAfterBuild

    dist directory contains Polymer site root after grunt build

    Run server:

    grunt serve

    yoPolymerServed

    HTML outputs to default browser automatically on port 9000

    Test (Local):

    grunt test

    yoPolymerTested

    HTML outputs to default browser automatically

  • 0 Comments
  • Filed under: Techniques, Tools
  • Getting Started with Polymer

    I have been trying out a few frameworks and tools for HTML development lately. So far, Polymer is the only one with something new and interesting about it that might be worth capturing here. This is a great place to try it out and find out what it is.

    bower

    The first step for trying Polymer for me was getting serious about using Bower. I had kicked it around while working with Angular but it didn’t work well with Intellij and I kinda dropped it. Intellij had a nice workaround and I didn’t have many dependencies, but polymer recommends it and has a ton of dependencies. So yeah, that means you will also need nodejs since Bower runs on it.

    To get rolling I tried the recommended bower installation approach. I got a directory with some files in it that I assume have something to do with Polymer. Whatever, not what I was looking for. Next, I downloaded the zip file from Your first Polymer app. It contains a set of tutorial files nicely staged out so that you can compare your incomplete solution to a correct final one – nice.

    Once I had the starter project laid out I was supposed to start running it in a web server – polymer doesn’t work with file:// URLs. Since I have nodejs on my path I could start a command window at the root of the starter project and enter

    start httpserver

    The tutorial recommends starting up a python server but too many complications on Windows, I don’t use Python etc. My server started up on port 8080, which was fine because that’s a port I use for throwaways.

    Why not 'Polymer in 10 Minutes'?

    Because I found it required too much foreknowledge about Polymer to learn anything basic. For example, Step 1 is “Load the Polymer core” -what? with a link that goes to the API reference. I tried loading the plunker examples (which refuse to open in a new tab) but sadly plunker was down. Later it says to “use an HTML Import to load the polymer.html dependency” but never shows the import statement, identifies what file it goes in, shows what it looks like, or where it goes in whatever unidentified file. This was became clear after I downloaded the tutorial, however.

  • 0 Comments
  • Filed under: Tools
  • Learn-along Maven 3: Integrating Selenium

    maven  Intellij Idea selenium

    In Learn-along Maven 3: Adding Dependencies I shared the way I add dependencies to a project to enable frameworks and libraries via Maven Project Object Model (POM).

    The dependencies satisfied the requirements for working with Java Server Pages, Struts 1.x, JBoss, testNg and Selenium. Together these will work with Java and JBoss Application Server to provide a testable web application.

    Since I started with the Hello World archetype I have some work to do to enable serving web pages with my application. All  the application can do from the start is print “Hello World!” out in the console, and verify that it works via a test class using jUnit.

    The Java Server Pages dependency provides a ready-made framework for delivering web pages via JBoss. Following the greased path outlined by the documentation, I added a web folder at the same level as src, and created a web page within it named “index.jsp”. This filename is the default for jsp/jBoss and will open when the directory containing it is reached in a browser. Then I added a folder within web named WEB_INF, and created a web.xml file in it which is used to define the jsp configuration for a j2ee compliant appllication server such as jBoss.

    To do this I need to create a web page within the project. I will  configure it within a standard web application format that JBoss can process and then deliver at a URL on my local computer. Then I will write a Selenium test that uses TestNg annotations and assertions to automatically open and verify that the page is launched in a specific browser and contains the content that I included when I created the web page.

    The Web Page

    <html>
    <head>
        <title>Welcome to simplest-struts</title>
    </head>
    <body>
    <p>simplest struts</p>
    </body>
    </html>

    Create a folder named “web” and save this html as “index.jsp” in it.

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
               version="2.5">
        <display-name>Simplest-Struts-1</display-name>
    
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    
        <servlet>
            <servlet-name>action</servlet-name>
            <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
            <init-param>
                <param-name>config</param-name>
                <param-value>/WEB-INF/struts-config.xml</param-value>
            </init-param>
            <load-on-startup>2</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>action</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    
    </web-app>

    SeleniumTest.java

    package com.davidjmcclelland;
    
    import com.thoughtworks.selenium.SeleneseTestBase;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;
    import org.testng.annotations.AfterClass;
    
    import org.apache.log4j.Logger;
    
    import static org.testng.Assert.assertTrue;
    
    public class SeleniumTest extends SeleneseTestBase {
        public static WebDriver driver = new FirefoxDriver();
        private final Logger logger = Logger.getLogger(SeleniumTest.class);
    
        public SeleniumTest(){
            super();
        }
    
        @BeforeClass
        public void setup(){
            logger.info("Setup class: " + this.getClass().getName());
            driver.get("http://localhost:8080/simplest_struts_1_Web_exploded/");
        }
    
        @Test
        public void titleTest(){
            assertTrue(driver.getPageSource().contains("simplest struts"));
        }
    
        @AfterClass
        public void tearDown(){
            driver.close();
            driver.quit();
        }
    
    }

    The Selenium test running from IntelliJ

  • 0 Comments
  • Filed under: Techniques, Tools
  • Learn-along Maven 3: Adding Dependencies

    maven  Intellij Idea 

    In Learn-along Maven 3: Hello World Tests Compared I compared running tests on a Hello World Java app using Intellij and various Maven approaches.

    In this post I will compare methods for adding libraries/dependencies. Where I am going with this is to take the Hello World archetype and make it into a webapp project and then test it with Selenium.

    • Add Java Server Pages
    • Add Struts 1.x
    • Add Selenium
    • Test locally in browser
    • Test in browser from Jenkins

    Libraries vs Dependencies...

    Adding libraries via the Intellij 12 module tab in project settings is not the same as adding Maven dependencies. I guess that seems obvious as I write this, but I would argue that if you create a Maven project it should behave consistently in a Maven-centric way. But when I add apache-log4j in the Project Structure dialog and select Library->Via Maven, a dependency is not added to the project POM file. The dependency storage format dropdown is a clue: the choices are IntelliJ or Eclipse formats, not Maven POM. The junit library that I added to the POM file manually is listed in Dependencies and has the prefix Maven: in front of it to indicate it is in the POM.

    I was hoping to find an integrated method for adding dependencies to the POM using IntelliJ 12 or 13, but so far I still find that pasting in a dependency block from Nexus Central repository is the best and easiest method.

    For several reasons:

    1. I am able to have a good look at the origin and version of the resource I am getting
    2. I am certain the dependency gets in the POM
    3. The resource is stored in the .m2 directory in the package where it belongs.
    4. I don’t have to manually figure out where to put the resource in the .m2 directory.
    5. I can update the resource by editing the POM entry and Intellij will download and install the update in the background

    Nexus Central vs. Intellij

    Nexus Central Repository shows resources in context, and rolled up in far fewer choices than a dropdown.

    A dropdown is insufficient when there are over 200 valid selections for “junit”

    A Library downloaded from a Maven Repo should default to saving in the appropriate package in the .m2 directory. I don’t want to guess where to put it when the correct answer should be in the artifact’s POM.

    Check the setting to Import Maven projects automatically

    Shortcomings/Challenges

    This aspect of developing in Java/Intellij is clunky compared to other stacks I have used. For example, to move a project from a simple “Hello World” command line test to a Struts WebApp required a lot of digging around to find the required libraries and versions- I finally “cheated” and opened the POM of another project and grabbed the entries form it to save time. There is no “Make this struts” button.

    A veteran Java developer would counter that “you just need to know what you’re doing.” That is true, of course. I know I can create a Struts project from an Archetype and get started. A wise developer needs to know what they are not doing. I need to focus my effort on developing what makes my project different and important enough to be funded. A strong library feature is a critical aspect of this.

    Once I found what I thought were the correct libraries/versions for Selenium, testNg, Struts and JSP were added to the POM there were several problems. Not having a real user interface to handle dependencies meant spending a lot of time Googling and comparing to other project to figure out. Eventually I got it sorted out and currently can run a test that opens a browser window to the page served by the webapp project.

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    xmlns="http://java.sun.com/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
               version="2.5">
        <display-name>Simplest-Struts-1</display-name>
    
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    
        <servlet>
            <servlet-name>action</servlet-name>
            <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
            <init-param>
                <param-name>config</param-name>
                <param-value>/WEB-INF/struts-config.xml</param-value>
            </init-param>
            <load-on-startup>2</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>action</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
        <jsp-config>
        <taglib>
            <taglib-uri>/tags/lab4-converter</taglib-uri>
            <taglib-location>/WEB-INF/lab4-converter.tld</taglib-location>
        </taglib>
        </jsp-config>
    
    </web-app>
  • 0 Comments
  • Filed under: Techniques, Tools
  • Learn-along Maven 3: Hello World Tests Compared

    maven  Intellij Idea console2Logo

    In Learn-along Maven 3: IDE vs CLI I compared creating a Hello World Java app via Maven using command line vs with IntelliJ using a Maven extension. The result was pretty much identical, but the process was slightly different between the two. Both projects ran green on Jenkins, although they really don’t do much and the test class is a bogus assertTrue(true).

    Now I will I will change the test to evaluate that the “Hello World” String is created as an accessible String and compare running the test

    • within Intellij,
    • within Intellij via Maven plugin,
    • with Maven via command line, and
    • via Jenkins.

    Change Main class and test assertion...

    Original archetype Hello World Class

    Testable Hello World class now has a variable message

    Replace the test assertion with this:

    assertTrue( App.message.equals(EXPECTED_STRING) );

    Test in IntelliJ...

    Build and run the test in Intellij by right-clicking the test class window tab or file icon.

    The target directory contains the build.

    Maven Test in IntelliJ...

    Maven Intellij plugin expands from the Right side by default, click Test in lifecycle…

    Test via Maven does not put empty annotation folders in target, otherwise the output looks the same as running the test from Intellij right-click menu, but its important to note that it is *not* the same thing.

    Maven Test from cmd.exe...

    mvn clean test

    Cmd shows the same information that is displayed in the Run log window in Intellij when you run a test via the Maven plugin.

    Output target directory was the same as running the maven plugin from within Intellij.

    Maven Test in Jenkins...

    Looks like the test runs great on Jenkins

    Wait something’s wrong: all Jenkins did was build an empty target folder structure. Nothing was run or tested at all. It’s a freestyle project – you have to enter the Maven commands.

    Make sure you enter “Invoke top-level Maven targets” which is the same thing as what was entered in the command line example.

    You should see test results at the bottom of the console log view.

    Maven’s workspace target directory now contains class files.

     

  • 0 Comments
  • Filed under: Techniques, Tools
  • Learn-along Maven 3: IDE vs CLI

    maven  Intellij Idea console2Logo

    Is there a difference between running Maven from within an IDE or directly in a command line? There shouldn’t be, but sometimes I have run into situations where I get different results between the two.

    When anything unexpected happens I tend to revert to the command line as a trusted source of truth. I don’t want my use of Maven with an integration tool like Jenkins, which requires a certain level of familiarity with its workings- to be limited if the IDE becomes a Maven crutch. On the other hand, if I can integrate my IDE with Jenkins via Maven there may be some interesting opportunities for automation and integration.

    So this will be a two-way comparison of Maven use and development via Intellij IDEA, which offers pretty good Maven support, and Console 2, the command line tool I use that combines Windows com, Powershell and Cygwin.

    Compare using Archetypes...

    Using IDEA to build archetype vs command line. Note that IDEA “sees” the POM in the my-app folder and claims the folder icon, but there is no .iml file present.

    Generating the archetype from within IDEA had the advantage of IDEA assigning the Maven type to the project from the start. The project I generated from the command line would have to be imported into IDEA as a Maven project to be worked with on that basis, and would then be identical to the one I created within IDEA.

    When I opened the CLI-created project directly from IDEA (as opposed to import Maven project) there were no project contents

    When I imported the CLI-generated project as a Maven project it became almost identical to the one IDEA generated in the first place.

    The IDEA-generated Archetype for comparison. Note I opted for the IDEA project settings as folder instead of single file – hence the .idea folder in this one only.

    One Difference Noted...

    This popped up when I reopened the IDEA-generated project. I thought IDEA already did this?

    after I clicked “auto-update” the dependencies folder was added and populated in the Maven panel. This was already present in the CLI-generated archetype.

  • 0 Comments
  • Filed under: Techniques, Tools
  • Categories





    Finger Lakes, NY

    United States of America

    Subscribe via Email

    Enter your email address to subscribe to this blog and receive notifications of new posts by email.