Using BettrData’s Transform.io JAR For Development (Advanced)

Using BettrData’s Transform.io JAR For Development (Advanced)

VS Code

Use the transform-io.jar supplied by BettrData support as a library in a small Scala project. VS Code can then check your override code, underline errors, suggest methods, and show parameter types.

Opening the JAR by itself does not enable Scala checking. You will edit a .scala file that references the JAR.

1. What you need

  • VS Code desktop for Windows, macOS, or Linux: Download VS Code.
  • A Java Development Kit (JDK). JDK 17 is a practical starting point for this editor setup; use your organization’s approved distribution, such as Eclipse Temurin. If support specifies a different JDK for your JAR, follow their instructions.
  • Scala (Metals), the VS Code extension published by Scalameta, extension ID scalameta.metals.
  • transform-io.jar from BettrData support.
  • Internet access for the initial Scala/build-tool downloads.

The starter project below uses Scala 2.12.18. This matches the Transform-io build used to check these examples. Ask support to confirm the Scala version for the JAR they sent you. Keep its exact version in build.sbt; do not change it to Scala 3 or Scala 2.13 to resolve an error.

You do not need the Transform-io source repository, a separate Scala installation, or a Java extension pack for these steps. Metals includes an sbt launcher for importing this project. A separate sbt installation is only needed for the optional terminal commands.

2. Install Scala support in VS Code

  1. Open VS Code.
  2. Select Extensions in the left sidebar, or press Ctrl+Shift+X on Windows/Linux or Cmd+Shift+X on macOS.
  3. Search for Scala (Metals). Check that the publisher is Scalameta and install the stable extension.
  4. Allow any requested window reload.
Picture 1 — Installing the stable Metals extension. Screenshot from the official Metals documentation; your VS Code appearance may differ.
Picture 1 — Installing the stable Metals extension. Screenshot from the official Metals documentation; your VS Code appearance may differ.

Extension details and supported editor features.

3. Create your checking project

Recommended: use the starter ZIP

Download and extract this starter. It contains the configuration and sample code shown below. The JAR is not included; copy the file already supplied by support into its lib folder.

bettrdata-vscode-starter.zip2.63 KiB

In VS Code, select File → Open Folder…, then choose the extracted bettrdata-override-check folder: the folder containing build.sbt. If VS Code asks about workspace trust, review the supplied project files and trust this folder to enable its build tools.

Or: create the files yourself

Create a folder named bettrdata-override-check with this layout. Use VS Code’s Explorer to create the folders and files. Copy the JAR with your operating system’s file manager.

bettrdata-override-check/
├── build.sbt
├── project/
│   └── build.properties
├── lib/
│   └── transform-io.jar
└── src/
    └── main/
        └── scala/
            └── OverrideCheck.scala

build.sbt — at the project root:

ThisBuild / scalaVersion := "2.12.18"
ThisBuild / organization := "local.bettrdata"
ThisBuild / version := "0.1.0"

name := "bettrdata-override-check"

scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked")

project/build.properties:

sbt.version=1.12.10

The sbt version above is an explicit 1.x project pin, independent of the Scala version. sbt release reference.

Keep the filename exactly transform-io.jar, rather than transform-io.jar.zip. Do not extract it. sbt automatically adds JARs placed in lib/ to this project’s classpath; no absolute file path or Maven publication is needed. sbt: local JAR dependencies.

4. Add a Runtime Override example

Create src/main/scala/OverrideCheck.scala and paste:

This example reads a mapped string field named city, trims it, and converts it to uppercase. Use fields and types that match your actual Output Schema. The compiler can check the method calls and Scala types, but cannot validate a schema field name written as a string.

The object OverrideCheck and val runtimeOverride lines give the snippet a valid home in an ordinary Scala 2 source file. The method shown includes the setup: Option[Any] parameter required by the checked JAR’s API. If your JAR has a different signature, use the signature shown by Metals for that JAR or ask support for its matching example.

5. Import the build

  1. Open OverrideCheck.scala.
  2. When Metals offers to Import build, select it.
  3. Wait for downloads, indexing, and compilation to finish. The first import can take several minutes.
Picture 2 — Choose Import build when Metals discovers the project. Official Metals example; its project name is unrelated to your BettrData project.
Picture 2 — Choose Import build when Metals discovers the project. Official Metals example; its project name is unrelated to your BettrData project.

If the prompt does not appear, open the Command Palette with Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on macOS, search for Metals: Import build, and run it.

Picture 3 — Import the build from the Command Palette. Screenshot from the official Metals documentation.
Picture 3 — Import the build from the Command Palette. Screenshot from the official Metals documentation.

Save the file after import. If you later change build.sbt, accept the re-import prompt. After replacing or adding JARs in lib/, run Metals: Import build again. Metals installation and build import.

6. Confirm that checking works

Use View → Problems to see errors and warnings.

Try this deliberate error: temporarily replace the last line inside overrideCode with:

holder.upsertField("city", "Denver")

Save the file. You should see a type mismatch: upsertField expects an Option[Any], while "Denver" is a plain String.

Restore the original line:

holder.upsertField("city", city)

Save again. That diagnostic should clear. You can also use Some("Denver") when intentionally supplying a constant value.

For everyday editing:

  • Type holder. and use Ctrl+Space to request completion.
  • Hover over Holder or a method to inspect its type.
  • Use F12 / Go to Definition to inspect available definitions. Library source availability depends on whether support supplied sources; a binary JAR does not guarantee full source documentation.
  • Save your work and check Problems before copying the code back.

Metals supports completion, hover information, and compile diagnostics; syntax errors can appear while typing, and type errors are reported on save. Metals feature list.

7. Copy the override back into BettrData

For the Runtime Override editor, copy only the anonymous override expression below. Omit the source file’s imports, object OverrideCheck, and val runtimeOverride = wrapper.

Leave a blank line before new RuntimeOverride when pasting. Some Transform-io versions prepend their own imports directly to the snippet, so the leading newline separates the statements.


new RuntimeOverride {
  override def overrideCode(
      holder: Holder,
      setup: Option[Any] = None
  ): Holder = {
    val city = holder.getFieldAs[String]("city")
      .map(_.trim.toUpperCase(java.util.Locale.ROOT))

    holder.upsertField("city", city)
  }
}

If your override uses additional libraries or helpers, include the imports and definitions required by your actual BettrData environment. Locally defined helper objects and globally configured BettrData snippets are not automatically copied between environments.

Run a small representative conversion in BettrData and inspect the output. Local compilation checks code structure and types; it does not verify field configuration, actual input values, external connections, or full job behavior.

8. Optional: check a Reduce Override

Create another file, src/main/scala/ReduceCheck.scala:

import io.phase3.transform.model._
import io.phase3.transform.service._

object ReduceCheck {
  val reduce: ReduceOverride = new ReduceOverride {
    override def reduceOverride(
        keyRecords: (String, Iterable[Holder]),
        dedupeType: String
    ): Iterable[Holder] = {
      keyRecords._2
    }
  }
}

This is a pass-through example that returns the group unchanged. It checks the method signature without demonstrating deduplication or changing business rules. Copy only new ReduceOverride { ... } into BettrData’s Reduce Override editor, with a leading newline.

9. Optional: compile from a terminal

If you have separately installed sbt, open Terminal → New Terminal in VS Code. From the folder containing build.sbt, run:

sbt compile

A successful compile ends with an sbt [success] message. To recompile when you save changes:

sbt "~compile"

Press Ctrl+C to stop continuous compilation. These sample objects have no main method; the objective is compilation. Running the full Transform-io engine locally requires a separate runtime setup from support.

10. Troubleshooting

Symptom
What to check
not found: object io, Holder, or RuntimeOverride
Confirm the JAR is in this project’s lib/, open the folder containing build.sbt, then run Metals: Import build.
Syntax colors appear but the deliberate type error is not reported
Confirm the extension is enabled, the file ends in .scala, and it is under src/main/scala/. Finish the build import and save the file.
“No build target” or import never starts
Open the project root rather than only a file or the lib/ folder. Check workspace trust and the Metals output.
A class such as Spark RDD, Jackson, or a Snowflake class is missing
A loose JAR does not automatically resolve all dependencies. Ask support for the matching editor dependency bundle or build configuration. Put supplied companion JARs in lib/ and re-import. If support supplies dependency lines instead, add them to build.sbt as directed.
“Scala signature,” incompatible Scala version, or duplicate Scala classes
Confirm scalaVersion matches the support-provided artifact. Remove conflicting Scala-version libraries; request a compatible editor bundle if the JAR embeds conflicting Scala classes.
“Overrides nothing” or “object creation impossible”
Compare the method parameters with the API in your JAR. In the checked example, overrideCode takes both holder and setup.
Java cannot be found or a Java-version error appears
Install a full JDK. In Settings, search for Metals “Java Home” and “Java Version”; check that they identify the intended JDK. Restart VS Code after changing Java settings.
Downloads fail behind a company proxy
Ask your IT team about access to the build repositories and the approved proxy/certificate configuration. Share the actual download error with support.
Code compiles locally but fails in BettrData
Check the deployed JAR version, field names, input types, global snippets, and runtime dependencies. Reproduce with a small input file.

For more detail, run Metals: Run Doctor from the Command Palette and inspect View → Output, selecting Metals or the relevant build output. Metals configuration and troubleshooting.

When contacting BettrData support, include your operating system, VS Code and Metals versions, JDK version (java -version), the JAR’s release/version, your build.sbt, and the exact error text. A small sanitized override is especially useful.

Compatibility and validation

Both sample files were compiled with Scala 2.12.18 against a local Transform-io 6.0.0 JAR on JDK 11. The deliberate String versus Option[Any] error was also confirmed by the compiler. The VS Code interface and JDK 17 setup were documented from the official tools’ instructions, rather than exercised in a live VS Code session.

Your support-provided JAR may be a different release. Its matching Scala version, method signatures, and dependency set take precedence over this example. The three pictures are official Metals screenshots, included as visual references and attributed above.