Build

Overview

Building an extension differs from a typically Windchill customization build, the primary difference being that the build is not done on a Windchill server. Instead of that, a standard Maven build is used, which is connected to an online repository provided by Wincom; this makes the whole process Windchill-independent, which means that the developer doesn't need a Windchill server in their machine to develop Windchill Extensions. During the build all required assets are downloaded automatically.

Building a Windchill Extension

Getting started

A quick and easy way to learn the build process is to access the Example 1 - Hello World section of this guide, located in the Developer Examples section, which provides the reader with information about the building and deploying of Windchill Extensions.

Configuration

Wincom provides extensions which the developer can use as dependencies in their projects; they are available on this online repository.

1616655969535

You must have create an account here

image-20240324184832030

and once you have one generate, save and download your settings.xml and place it in you {user-home}/.m2 folder

image-20240324185454252

Please note that it may take several minutes for this to become active.

After that, every time the developer builds an extension which needs dependencies from the online repository, Maven will automatically download them from it and store them in their m2 folder for future usage.

Please note Wincom does not store the login information as this is managed by Microsoft

Creating a new project using an Archetype

You can create a blank project using an archetype (a type of template)

image-20240428191036415

image-20240428191414291

image-20240428191541857

You can now build this for your version of Windchill

image-20240428192202666

The resulting extension will appear in the targets folder

Troubleshooting

In certain networks, the access to the nexus.wex.solution server may be restricted and the server is not available during build even if the server can be reached via a browser, throwing an error like the one seen below:

image-20220613200621170

In that case, please look at how to setup Maven for a proxy.

Creating a new commons using an Archetype

A commons is a shared java library that contains only Java code. It cannot be annotated but may call the kernel e.g. wex invoke. It is managed as a version controlled entity including the winchill version it supports. They are held in the repo, as is the archetype. and can be referenced in the pom

The archetype is called wex-archetype-commons

Archetype Generation Command

This command is used to create a new empty shell of an extension:

mvn archetype:generate 
        -DarchetypeGroupId=<archetype-groupId>
        -DarchetypeArtifactId=<archetype-artifactId>
        -DarchetypeVersion=<archetype-version>
        -DgroupId=<my.groupid>
        -DartifactId=<my-artifactId>
        -Dpackage=com.wincomplm.wex.<artifactId>

As in the following example:

mvn archetype:generate -DarchetypeGroupId=com.wincomplm -DarchetypeArtifactId=wex-archetype -DarchetypeVersion=1.1 -DgroupId=com.mycompany -DartifactId=wex-myproject -Dversion=1.0b1 -Dpackage=com.mycompany.wex.mytest.project

It is good practice to use this archetype as a starting point when developing Windchill Extensions.

Building in an IDE

All modern Java IDEs support Apache Maven, and the extensions can be build within the IDE as normal.

Apache NetBeans Example

1616655976829

Eclipse Example

1620678907087

Example Build

1616786508913

Build Architecture

POM

The Maven build uses the pom.xml to build the Java code. The pom file has the following sections:

Parent

<parent>
    <groupId>com.wincomplm</groupId>
    <artifactId>wex-parent</artifactId>
    <version>x.x</version>
</parent>

The parent tells Maven how to build the project and to include all the plugins required to build the extensions, while providing the child entity with a set of versions for matching with the extension's dependencies during the building process. A higher version of the parent will mean a more recent version of the dependencies listed in the pom will be included in the build.

Properties

    <properties>
        <major>1</major>
        <minor>0</minor>
        <beta>1</beta>
        <revision>${major}.${minor}-${wex.wt}</revision>
    </properties>

This section holds the versions that are used to populate both the final .wex file and the information held in the definition.xml file, which is used by the platform to identify the extension's version.

Identity Block

<groupId>com.acme</groupId>
<artifactId>wex-helloworld</artifactId>
<version>${revision}</version>

A Windchill Extension is uniquely identified by two parameters: the groupId and the artifactId. These are combined to form a unique wexId that is used in the platform to uniquely identify a WEX. The artifactId field should match your organization.

Dependencies

    <dependencies>
        <dependency>
            <groupId>com.ptc</groupId>
            <artifactId>windchill-pdmlink</artifactId>
        </dependency>
        <dependency>
            <groupId>com.wincomplm</groupId>
            <artifactId>wex-kernel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.wincomplm</groupId>
            <artifactId>wex-system</artifactId>
        </dependency>
        <dependency>
            <groupId>com.wincomplm</groupId>
            <artifactId>wt-framework-commons</artifactId>
            <version>1.3-${wex.wt}</version>
        </dependency>
        <dependency>
            <groupId>groovy</groupId>
            <artifactId>groovy-xmlrpc</artifactId>
            <version>0.3</version>
        </dependency>
    </dependencies> 

This section lists all of the dependencies that Maven will collect when building the Windchill Extensions. There are some mandatory entries when building a WEX: windchill-pdmlink, wex-kernel and wex-system always need to be in this list.

Those three cases are a good example of provided dependencies: they are anticipated to be available on the target system so they are not placed in the extension's own codebase and they can be identified and declared as such with the <scope>provided</scope> tag. In the case of a commons WEX, however, that would not be the desired behavior, as we don't want them to act as a shared library: a unique copy of it must be placed in the extension. The absence of the <scope>provided</scope> tag will include the JAR file in the final build's own codebase, which will make it not visible to Windchill, thus preserving isolation.

A 3rd party open source library may be included as a dependency: again, this will be placed in the extension's isolated class path, meaning we can have extensions that use different version of the same library deployed in the same Windchill system. Since the system uses a standard Maven build, we can also include our own plugins and specialized build tools.

WEX Definition File

In addition to the POM file, each extension has a definition.xml file which is stored in the following path:

src/main/wex/meta/definition.xml 

The purpose of this file is to identify the extension and to give the deployment mechanism the necessary information on how to install the WEX. It also contains information added by the signing process. It's good practice to define values such as the version number, groupId and artifactId in the pom.xml file and then reuse them in this one. The definition.xml file is composed by the following blocks:

Meta

    <meta>
        <group-id>${groupId}</group-id>      
        <artifact-id>${artifactId}</artifact-id>      
        <display-name>Hello World</display-name>
        <system>false</system> 
        <description>Hello to the world</description>  
    </meta>

The values in this block are used by the Extension Manager to display the extension's metadata. The system field is a noteworthy one, since it defines whether the extension is a system one or not: it should be kept as false except for very particular cases.

Important: Wincom will not support any system malfunctions generated by a misuse of this tag.

Build

    <build>
        <version>
            <major>${major}</major>
            <minor>${minor}</minor>
            <beta>${beta}</beta>
        </version>
        <host>
            <release>${wex.wt}</release>
        </host>
    </build>

This block defines the release version and target host's version (e.g. 12.1). The beta field is optional, and will be ignored if not included in the version tag in the POM file.

All the tags are mandatory in file, but beta may be blank.

Install

<install>
    <menus>
        <extension menu="more parts actions" file="PartClient-actionmodels" action="edkHelloWorld"/>
        <extension menu="header actions" file="navigation-actionModels" action="edkHelloWorldNonPop"/>

    </menus>
    <actions>
        <wizard name="edkHelloWorld"   url="edkHelloWorld.jsp" shortcut="false"/>
        <page name="edkHelloWorldNonPop"   url="edkHelloWorld.jsp"/>

    </actions>

</install>

This block is used to instruct the Extension Manager how to install the extension and what modifications it needs to make to the Windchill system to, for example, add menu entries.

Client

This block can exist or maybe added by the signing service. Note that free signing is allowed but will only sign the extension as a trial

   <additional>
      <trial>false</trial>
      <timestamp>1710972501640</timestamp>
      <expires>0</expires>
      <client-id>604566</client-id>
      <client-name>Acme SL</client-name>
      <user-id>simonh@wincom-consulting.com</user-id>
    </additional>

The information in this block will appear in the manager. The client id and user id will not be shown

image-20240324111840000

WEX File Structure

The result of a successful build process for an extension is a .wex file that is in ZIP format and presents the following structure:

groupId
--- artifactId
------- bootstrap.xml => Scope information
------- codebase
-------------- JAR files used for the isolated classloader
------- docs
------- meta
-------------- definition.xml => Definition of the extension
------- windchill

1622019214202

From a build point of view, the following are the most relevant files and folders:

bootstrap.xml

This file is generated during the build and its purpose is to manage which files are allowed in the codebase. This is used on startup to remove any unauthorized files and ensure the signing is not violated by old JAR files from previous releases being present.

It also includes elements that are used by the kernel to construct the cascading class loading. In broad terms, it holds the statically (classpath tag) and dynamically (required tag) used elements. An example of it would look like the one below:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bootstrap>
    <uid>com.wincomplm.wex-report-designer</uid>
    <service>com.wincomplm.wex.report.designer.impl.bootstrap.WexBootstrap</service>
    <classpath>
        <element>codebase/wex-config-aux-1.1-11.1.jar</element>
        <element>codebase/wt-ui-commons-1.2-11.1.jar</element>
        <element>codebase/wt-query-builder-commons-1.0-11.1.jar</element>
        <element>codebase/unbescape-1.1.6.RELEASE.jar</element>
        <element>codebase/wt-security-commons-1.1-11.1.jar</element>
        <element>codebase/wex-store-commons-1.0-11.1.jar</element>
        <element>codebase/wt-framework-commons-1.3-11.1.jar</element>
        <element>codebase/wex-bo-info-commons-1.1-11.1.jar</element>
        <element>codebase/wex-core-aux-1.0-11.1.jar</element>
        <element>codebase/wt-appdata-commons-1.4-11.1.jar</element>
        <element>codebase/wt-dataprovider-commons-1.4-11.1.jar</element>
        <element>codebase/pdfbox-2.0.23.jar</element>
        <element>codebase/thymeleaf-3.0.11.RELEASE.jar</element>
        <element>codebase/groovy-3.0.7.jar</element>
        <element>codebase/wex-report-commons-1.1-11.1.jar</element>
        <element>codebase/boxable-1.5.jar</element>
        <element>codebase/ognl-3.1.12.jar</element>
        <element>codebase/fontbox-2.0.23.jar</element>
        <element>codebase/gson-2.8.5.jar</element>
        <element>codebase/attoparser-2.0.5.RELEASE.jar</element>
        <element>codebase/commons-text-1.9.jar</element>
        <element>codebase/wex-report-designer.jar</element>
    </classpath>
    <required>
        <uid>com.wincomplm.wex-log</uid>
        <uid>com.wincomplm.wex-system</uid>
        <uid>com.wincomplm.wex-store</uid>
        <uid>com.wincomplm.wex-wt-framework</uid>
        <uid>com.wincomplm.wex-config</uid>
        <uid>com.wincomplm.wex-core</uid>
    </required>
</bootstrap>

codebase

In this folder are the files that will be loading into the class loader (not cascaded) using the bootstrap.xml file as the source of truth (the files themselves are not used as the source of truth for security reasons).

windchill

All files in this folder will be transferred on deploy to Windchill home. They should not replace any existing file as they will be removed if the extension is undeployed.

Maven Tools

Build Options

The developer may wish to control the options of the extension build to improve performance and adjust the build to, for example, prevent obfuscation in order to assist with debugging. This can be achieved through the passing of options to the compiler.

Following are some common options:

Name Default Description
cve.check.skip false Prevent security checks on dependencies.
wex.sign true Signs the extension
obfuscate false Obfuscate code (requires the obfuscation build module).
wex.sign.service.url false Use alternative signing service.
windchill.api.disable false Disable api scan (WVE/SCA)
windchill.api.skip false Prevents build stopping for WVE or SCA errors
windchill.api.approved List of approved dependencies
wex.security.wvedb Wincom's own db Specify a .json file with WVE Security Levels which will determine what Security Level the WEX is on build.
wex.security.wveadb Wincom's own db Specify a .json file with WVE Approvals for Extensions.
wex.security.scaadb Wincom's own db Specify a .json file with dependency (CVE) approvals for Extensions.
complexity.limit 8 Default cyclomatic complexity limit

In Apache NetBeans these parameters can be inputted in Tools > Options > Java > Maven as seen in the screenshot below:

1616960698610

Cyclomatic Complexity

By using the wex-parent you will ensure your code does not exceed complexity limits, you should be keeping methods under the magic number which is important for code quality but also for security. Read here for more details on complexity

image-20230808114528206

If your code has issues but you do not want to alter it (often a wise choice if the code is already being used) you may add a custom limit (wex-parent 2.46 and above)

-Dcomplexity.limit=20

Dependencies

Maven will collect and manage dependencies. The latest Wincom build tool from wex-builder 1.6 will check for any inconsistencies and automatically add all required 3rd party dependencies into the WEX from any dependent library.

We can check the generated WEX's codebase in order to make sure it included all libraries that were declared in our pom.xml file.

1629197305605

If different versions of the same library are included by different dependencies, an error will be thrown and the build process will be stopped with a failure. It is crucial that, despite the fact that different Windchill Extensions are able to use different versions of the same library when deployed in one system due to the platform's isolation design principles, no two different versions of the same library can be at the same time in one WEX. In other words, no two versions of the same library can be placed in one codebase.

We can use the dependency:tree option to find the source of the problem when facing errors like this one, and adjust the versions to allow a correct build to happen:

1629198738686

In wex-parent 2.42 onwards you can define your own wve and sca approvals .json file to manage your approved dependencies and WVE's. If there is a CVE that you determine does not have an attack surface you can add the approval to the specified .json file.

An example of a WVE Approval is:

[
    {
        "id": "com.wincomplm.wex-example-security",
        "rules": ["WVE-2022-0204","WVE-2022-0101","WVE-2022-0201","WVE-2022-0202","WVE-2022-0301","WVE-2022-0401","WVE-2022-0402","WVE-2022-0403","WVE-2022-0501","WVE-2022-0501"],
        "falsePositives": ["WVE-2022-0301"]    
    }
]

An example of a sca approval is:

[
    {
        "groupId": "com.wincomplm",
        "artifactId": "*",
        "versions": ["*"]
    }
]

If you would like to skip this process use the api.skip and api.approved shown above in Build Options.

Development Mode in Tomcat

In Windchill, Java Server Pages are cached by Tomcat. This means that, if you deploy the same page with the same name, then the page will not be recompiled. By adding the following change in Tomcat, the page will be reloaded if the timestamps changes.

From Windchill 11 onwards the system will recompile the JSP if the Method Server is restarted.

Edit this file:

%WT_HOME%\tomcat\conf\web.xml

and adjust this parameter:

   <init-param>
       <param-name>development</param-name>
       <param-value>true</param-value>
   </init-param>

After that, restart your system.

Adding External JAR Files

In order to import a file into your build, follow these steps:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<groupid> -DartifactId=<DartifactId>

For example:

mvn install:install-file –Dfile=windmod.jar -DgroupId=com.ptc -DartifactId=mywindchillmod -Dversion=12.0.2
    <dependency>
        <groupId>com.ptc</groupId>
        <artifactId>mywindchillmod</artifactId>
        <version>12.0.2</version>
    </dependency>