Ron and Ella Wiki Page

Extremely Serious

Page 29 of 33

Structural Design Patterns

Structural design patterns deal with the composition of classes and objects to create larger, more complex structures while keeping the system flexible and easy to maintain. They are concerned with object relationships and the assembly of objects to form more significant structures. These patterns help to solve common design problems by promoting object reusability and flexibility.

Adapter Pattern

The Adapter Pattern allows incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces, making them work seamlessly.

Example

interface NewInterface {
    void doSomethingNew();
}

class LegacyLibrary {
    void doSomethingOld() {
        // Legacy implementation
        System.out.println("Legacy implementation");
    }
}

class LegacyAdapter implements NewInterface {
    private LegacyLibrary legacyLibrary;

    public LegacyAdapter(LegacyLibrary legacyLibrary) {
        this.legacyLibrary = legacyLibrary;
    }

    @Override
    public void doSomethingNew() {
        legacyLibrary.doSomethingOld();
    }
}

public class Main {
    public static void main(String[] args) {
        NewInterface newObject = new LegacyAdapter(new LegacyLibrary());
        newObject.doSomethingNew();
    }
}

Bridge Pattern

The Bridge Pattern separates an object's abstraction from its implementation, allowing them to vary independently.

Example

interface DrawingAPI {
    void drawCircle(double x, double y, double radius);
}

class DrawingAPI1 implements DrawingAPI {
    public void drawCircle(double x, double y, double radius) {
        System.out.println("Implementation 1");
    }
}

class DrawingAPI2 implements DrawingAPI {
    public void drawCircle(double x, double y, double radius) {
        System.out.println("Implementation 2");
    }
}

abstract class Shape {
    protected DrawingAPI drawingAPI;

    protected Shape(DrawingAPI drawingAPI) {
        this.drawingAPI = drawingAPI;
    }

    public abstract void draw();
}

class Circle extends Shape {
    private double x, y, radius;

    public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {
        super(drawingAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public void draw() {
        drawingAPI.drawCircle(x, y, radius);
    }
}

public class Main {
    public static void main(String[] args) {
        DrawingAPI api1 = new DrawingAPI1();
        Shape circle1 = new Circle(1, 2, 3, api1);
        circle1.draw();
    }
}

Composite Pattern

The Composite Pattern allows you to compose objects into tree structures to represent part-whole hierarchies. It treats individual objects and compositions of objects uniformly.

Example

import java.util.ArrayList;
import java.util.List;

interface Graphic {
    void draw();
}

class Circle implements Graphic {
    public void draw() {
        System.out.println("Drawing circle.");
    }
}

class Square implements Graphic {
    public void draw() {
        System.out.println("Drawing square.");
    }
}

class CompositeGraphic implements Graphic {
    private List<Graphic> graphics = new ArrayList<>();

    public void add(Graphic graphic) {
        graphics.add(graphic);
    }

    public void draw() {
        System.out.println("Drawing all graphics.");
        for (Graphic graphic : graphics) {
            graphic.draw();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        CompositeGraphic composite = new CompositeGraphic();
        composite.add(new Circle());
        composite.add(new Square());
        composite.draw();
    }
}

Decorator Pattern

The Decorator Pattern allows you to add behavior to objects dynamically, without altering their class.

Example

interface Coffee {
    double cost();
    String description();
}

class SimpleCoffee implements Coffee {
    public double cost() {
        return 2.0;
    }

    public String description() {
        return "Simple Coffee";
    }
}

abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee decoratedCoffee) {
        this.decoratedCoffee = decoratedCoffee;
    }

    public double cost() {
        return decoratedCoffee.cost();
    }

    public String description() {
        return decoratedCoffee.description();
    }
}

class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

    public double cost() {
        return super.cost() + 1.0;
    }

    public String description() {
        return super.description() + ", Milk";
    }
}

public class Main {
    public static void main(String[] args) {
        Coffee coffee = new MilkDecorator(new SimpleCoffee());
        System.out.println("Cost: $" + coffee.cost());
        System.out.println("Description: " + coffee.description());
    }
}

Facade Pattern

The Facade Pattern provides a simplified interface to a complex system of classes, making it easier to use and understand. It acts as a "facade" or entry point to access a group of related interfaces and classes.

Example

class CPU {
    public void start() {
        System.out.println("CPU start");
    }

    public void shutdown() {
        System.out.println("CPU shutdown");
    }
}

class Memory {
    public void load() {
        System.out.println("Memory load");
    }

    public void unload() {
        System.out.println("Memory unload");
    }
}

class HardDrive {
    public void read() {
        System.out.println("Hard drive read");
    }

    public void write() {
        System.out.println("Hard drive write");
    }
}

class ComputerFacade {
    private CPU cpu;
    private Memory memory;
    private HardDrive hardDrive;

    public ComputerFacade() {
        this.cpu = new CPU();
        this.memory = new Memory();
        this.hardDrive = new HardDrive();
    }

    public void start() {
        cpu.start();
        memory.load();
        hardDrive.read();
    }

    public void shutdown() {
        cpu.shutdown();
        memory.unload();
        hardDrive.write();
    }
}

public class Main {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start();
        computer.shutdown();
    }
}

Filter Pattern

The Filter Pattern allows you to create a chain of filter objects to process a request. Each filter performs some filtering or processing on the request and passes it to the next filter in the chain.

Example

import java.util.ArrayList;
import java.util.List;

class Product {
    private String name;
    private String category;
    private double price;

    public Product(String name, String category, double price) {
        this.name = name;
        this.category = category;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public String getCategory() {
        return category;
    }

    public double getPrice() {
        return price;
    }
}

interface Filter {
    List<Product> filter(List<Product> products);
}

class CategoryFilter implements Filter {
    private String category;

    public CategoryFilter(String category) {
        this.category = category;
    }

    @Override
    public List<Product> filter(List<Product> products) {
        List<Product> filteredProducts = new ArrayList<>();
        for (Product product : products) {
            if (product.getCategory().equalsIgnoreCase(category)) {
                filteredProducts.add(product);
            }
        }
        return filteredProducts;
    }
}

class PriceRangeFilter implements Filter {
    private double minPrice;
    private double maxPrice;

    public PriceRangeFilter(double minPrice, double maxPrice) {
        this.minPrice = minPrice;
        this.maxPrice = maxPrice;
    }

    @Override
    public List<Product> filter(List<Product> products) {
        List<Product> filteredProducts = new ArrayList<>();
        for (Product product : products) {
            double price = product.getPrice();
            if (price >= minPrice && price <= maxPrice) {
                filteredProducts.add(product);
            }
        }
        return filteredProducts;
    }
}

class ProductFilter {
    public static List<Product> applyFilter(List<Product> products, Filter filter) {
        return filter.filter(products);
    }
}

public class Main {
    public static void main(String[] args) {
        List<Product> products = new ArrayList<>();
        products.add(new Product("Laptop", "Electronics", 1000.0));
        products.add(new Product("Phone", "Electronics", 500.0));
        products.add(new Product("Shirt", "Clothing", 25.0));
        products.add(new Product("Dress", "Clothing", 50.0));
        products.add(new Product("Book", "Books", 15.0));

        System.out.println("Electronics products:");
        List<Product> electronicsProducts = ProductFilter.applyFilter(products, new CategoryFilter("Electronics"));
        printProducts(electronicsProducts);

        System.out.println("\nProducts in the price range $20 - $100:");
        List<Product> priceRangeProducts = ProductFilter.applyFilter(products, new PriceRangeFilter(20.0, 100.0));
        printProducts(priceRangeProducts);
    }

    public static void printProducts(List<Product> products) {
        for (Product product : products) {
            System.out.println("Name: " + product.getName() + ", Category: " + product.getCategory() +
                    ", Price: $" + product.getPrice());
        }
    }
}

Flyweight Pattern

The Flyweight Pattern is used to minimize memory usage or computational expenses by sharing as much as possible with related objects. It is particularly useful when you have a large number of similar objects, and you want to reduce memory usage by sharing common data among them.

Example

import java.util.HashMap;
import java.util.Map;

class Character {
    private char symbol;

    public Character(char symbol) {
        this.symbol = symbol;
    }

    public void display(int fontSize) {
        System.out.println("Character: " + symbol + ", Font Size: " + fontSize);
    }
}

class CharacterFactory {
    private Map<java.lang.Character, Character> characters = new HashMap<>();

    public Character getCharacter(char symbol) {
        if (!characters.containsKey(symbol)) {
            characters.put(symbol, new Character(symbol));
        }
        return characters.get(symbol);
    }
}

public class Main {
    public static void main(String[] args) {
        CharacterFactory characterFactory = new CharacterFactory();
        Character charA = characterFactory.getCharacter('A');
        Character charB = characterFactory.getCharacter('B');
        charA.display(12);
        charB.display(16);
    }
}

Proxy Pattern

The Proxy Pattern provides a surrogate or placeholder for another object to control access to it. It allows you to add an additional level of control over object access, such as lazy loading, access control, or monitoring.

Example

interface Image {
    void display();
}

class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading " + filename);
    }

    public void display() {
        System.out.println("Displaying " + filename);
    }
}

class ProxyImage implements Image {
    private RealImage realImage;
    private String filename;

    public ProxyImage(String filename) {
        this.filename = filename;
    }

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

public class Main {
    public static void main(String[] args) {
        Image image = new ProxyImage("large_image.jpg");
        image.display();
    }
}

Creational Design Patterns

Creational design patterns are a subset of design patterns in software engineering that focus on the process of object creation. These patterns provide various ways to instantiate objects while hiding the complexities involved in the process. Creational design patterns promote flexibility, reusability, and maintainability in your codebase. In this article, we'll explore some of the most commonly used creational design patterns with java examples.

Abstract Factory Pattern

Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

Example

interface IShape {
    void draw();
}

abstract class AbstractShapeFactory {
    abstract IShape getShape(String targetShape);
}

class Circle implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing circle.");
    }
}

class Square implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing square.");
    }
}

class Rectangle implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing rectangle.");
    }
}

class NormalShapeFactory extends AbstractShapeFactory {
    @Override
    IShape getShape(String targetShape) {
        return switch(targetShape.toLowerCase()) {
            case "circle" -> new Circle();
            case "square" -> new Square();
            case "rectangle" -> new Rectangle();
            default -> null;
        };
    }
}

class RoundedSquare implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing rounded square.");
    }
}

class RoundedRectangle implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing rounded rectangle.");
    }
}

class RoundedShapeFactory extends AbstractShapeFactory {
    @Override
    IShape getShape(String targetShape) {
        return switch(targetShape.toLowerCase()) {
            case "circle" -> new Circle();
            case "square" -> new RoundedSquare();
            case "rectangle" -> new RoundedRectangle();
            default -> null;
        };
    }
}

class ShapeFactoryProducer {
    public static AbstractShapeFactory getFactory(String shapeType){
        return switch (shapeType.toLowerCase()) {
            case "rounded" -> new RoundedShapeFactory();
            default -> new NormalShapeFactory();
        };
    }
}

public class Main {
    public static void main(String[] args) {
        AbstractShapeFactory normalShapeFactory = ShapeFactoryProducer.getFactory("normal");
        IShape normalSquare = normalShapeFactory.getShape("square");
        normalSquare.draw();

        AbstractShapeFactory roundedShapeFactory = ShapeFactoryProducer.getFactory("rounded");
        IShape roundedSquare = roundedShapeFactory.getShape("square");
        roundedSquare.draw();
    }
}

Builder Pattern

Separates the construction of a complex object (i.e. requires a lot of constructors and properties) from its representation, allowing the same construction process to create different representations.

Example

class Product {
    private String part1;
    private String part2;

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    public void show() {
        System.out.println("Part 1: " + part1);
        System.out.println("Part 2: " + part2);
    }
}

class ProductBuilder {
    private String part1;
    private String part2;

    public ProductBuilder buildPart1(String part1) {
        this.part1 = part1;
        return this;
    }

    public ProductBuilder buildPart2(String part2) {
        this.part2 = part2;
        return this;
    }

    public Product build() {
        Product product = new Product();
        product.setPart1(part1);
        product.setPart2(part2);
        return product;
    }
}

public class Main {
    public static void main(String[] args) {
        ProductBuilder builder = new ProductBuilder();
        Product product = builder
            .buildPart1("Part 1")
            .buildPart2("Part 2")
            .build();

        product.show();
    }
}

Factory Pattern

Defines an interface for creating an object but allows subclasses to alter the type of objects that will be created.

Example

interface IShape {
    void draw();
}

interface IShapeFactory {
    IShape createShape(String shapeType);
}

class Circle implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing circle.");
    }
}

class Rectangle implements IShape {
    @Override
    public void draw() {
        System.out.println("Drawing rectangle.");
    }
}

class ShapeFactory implements IShapeFactory {
    @Override
    public IShape createShape(String shapeType) {
        if (shapeType.equals("circle")) {
            return new Circle();
        }
        else if (shapeType.equals("rectangle")) {
            return new Rectangle();
        }
        else {
            throw new IllegalArgumentException("Invalid shape type: " + shapeType);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();
        IShape shape = shapeFactory.createShape("circle");
        System.out.println(shape);
    }
}

Lazy Initialization Pattern

Delays the creation of an object or the calculation of a value until it is actually needed.

Example

class LightObject1 {
    public LightObject1() {
        System.out.println("LightObject1 initialized");
    }
}

class LightObject2 {
    public LightObject2() {
        System.out.println("LightObject2 initialized");
    }
}

class ExpensiveObject {
    public ExpensiveObject() {
        // Simulate a time-consuming initialization process
        try {
            Thread.sleep(2000); // Sleep for 2 seconds to simulate initialization time
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ExpensiveObject initialized");
    }
}

class LazyInitialization {
    // Lightweight objects to be instantiated in the constructor
    private LightObject1 lightObject1;
    private LightObject2 lightObject2;

    // Declare a private field to hold the lazily initialized object
    private ExpensiveObject expensiveObject;

    public LazyInitialization() {
        // Instantiate the lightweight objects in the constructor
        lightObject1 = new LightObject1();
        lightObject2 = new LightObject2();
    }

    // This method initializes and returns the expensive object on-demand
    public ExpensiveObject getExpensiveObject() {
        if (expensiveObject == null) {
            // Lazy initialization: Create the expensive object when it's first requested
            expensiveObject = new ExpensiveObject();
        }
        return expensiveObject;
    }
}

public class Main {
    public static void main(String[] args) {
        LazyInitialization example = new LazyInitialization();

        // At this point, the lightweight objects are already instantiated,
        // but the expensive object has not been created yet
        System.out.println("Lightweight objects initialized");
        System.out.println("Expensive object not yet initialized");

        // When needed, get the expensive object
        ExpensiveObject obj = example.getExpensiveObject();

        // Now, the expensive object has been initialized
        System.out.println("Expensive object initialized");
    }
}

Prototype Pattern

Creates new objects by copying an existing object, known as the prototype, rather than instantiating new objects using constructors.

Example

class Prototype implements Cloneable {
    private String name;

    public Prototype(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public Prototype clone() throws CloneNotSupportedException {
        return (Prototype) super.clone();
    }
}

public class Main {

    public static void main(String ... args) {
        Prototype prototype1 = new Prototype("Prototype 1");

        try {
            Prototype prototype2 = prototype1.clone();
            System.out.println("Clone: " + prototype2.getName()); // Output: Clone: Prototype 1
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

Singleton Pattern

Ensures that a class has only one instance and provides a global point of access to that instance.

Example

final class Singleton {
    private static Singleton instance;

    private Singleton() {
        // Private constructor to prevent instantiation
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

public class Main {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        System.out.println(singleton1);
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton2);
    }
}

Hashing a Password in Java

  1. Create an instance of SecretKeyFactory using the desired algorithm (see. https://docs.oracle.com/javase/8/docs/api/index.html?javax/crypto/SecretKeyFactory.html) like the following:
    SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");

    Note: The PBKDF2WithHmacSHA512 is the algorithm to construct the secret key using the Password-Based Key Derivation Function.

  2. Synthesize the raw materials into the instance of PBEKeySpec using the following syntax:
    PBEKeySpec spec = new PBEKeySpec( <PASSWORD>, <SALT>, <ITERATIONS>, <KEY_LENGTH> );
    Parameter Description
    <PASSWORD> The raw password (i.e. in array of chars)
    <SALT> A text (i.e. in array of bytes) that will be included to password.
    <ITERATIONS> The desired number of iterations that the <PASSWORD> along with the <SALT> will be encoded. The higher the number the better to deter some kind of attack (e.g. rainbow).
    <KEY_LENGTH> The length (i.e. in bits) of the key. Normally you can find this value on the algorithm name (e.g. PBKDF2WithHmacSHA512).
  3. Create a SecretKey instance using the spec from step 2 using the following:
    SecretKey key = skf.generateSecret(spec);
  4. Retrieve the encoded hash using the getEncoded() method of the SecketKey instance like the following:
    byte[] encodedKey = key.getEncoded();
  5. Use Base64 encoder to  covert the encoded key to string like the following:
    String base64Str = Base64.getEncoder().encodeToString(encodedKey);

Example code

package xyz.ronella.crypto;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;

public class PasswordHashing {
    public static void main(String[] args) {
        try {
            SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");

            PBEKeySpec spec = new PBEKeySpec("PASSWORD".toCharArray(), "SALT".getBytes(), 10000, 512);
            SecretKey key = skf.generateSecret(spec);

            byte[] encodedKey = key.getEncoded();
            String base64Str = Base64.getEncoder().encodeToString(encodedKey);

            System.out.println(base64Str);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }
}

Always On Top using AutoHotKey

  1. Create an autohotkey script (e.g. alwaysontop.ahk).
  2. Add the following entries:
    #^+t::
    	WinSet, AlwaysOnTop, On, A
    Return
    
    #^t::
    	WinSet, AlwaysOnTop, Off, A
    Return

    Example script

    #NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
    ; #Warn  ; Enable warnings to assist with detecting common errors.
    SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
    SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
    
    #^+t::
    	WinSet, AlwaysOnTop, On, A
    Return
    
    #^t::
    	WinSet, AlwaysOnTop, Off, A
    Return

To make a window always on top press the following combination:

Win + Ctrl + Shift + t

To disable the effect of the always on top press the following combination:

Win + Ctrl + t

Changing Jenkins Port

  1. Open the file jenkins.xml from the location where Jenkins was installed (e.g. C:\Program Files (x86)\Jenkins).
  2. Search for httpPort and updated it with whatever you wanted it to be (e.g. 9080) as long as it doesn't introduce any conflicts.

    Example update to 9080

    <arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=9080 --webroot="%BASE%\war"</arguments>

RegEx Negative Look Behind with Sublime

Negative look behind with regex is another useful constraint that we can add to our expression. It only matches the right side, if and only if the look behind doesn't match. The look behind doesn’t consume any characters and has the following syntax:

(?<!<look behind>)<right side>

Example:

<?xml version="1.0"?>
<fruits>
 <a>apple</a>
 <b></b>
 <c>cashew</c>
 <d></d>
</fruits>

From the XML above find all the empty elements and add an attribute empty that is set to true but only matching the opening tag.

Find Replace Comment
(?<!^<)<(?<tag>\w*[^>])>(?=<) <$1 empty=”true”> The negative <look behind> is the one highlighted in blue.

The <right side> is the one highlighted in green.

RegEx Positive Look Behind with Sublime

Positive look behind with regex is another useful constraint that we can add to our expression. It only matches the right side, if and only if the look behind matches. The look behind doesn’t consume any characters and has the following syntax:

(?<=<look behind>)<right side>

Example:

<?xml version="1.0"?>
<fruits>
 <a>apple</a>
 <b></b>
 <c>cashew</c>
 <d></d>
</fruits>

From the XML above find all the empty elements and add an attribute empty that is set to true but only matching the opening tag.

Find Replace Comment
(?<=\n\s)<(?<tag>\w*[^>])>(?=<) <$1 empty=”true”> The positive <look behind> is the one highlighted in blue.

The <right side> is the one highlighted in green.

RegEx Negative Look Ahead with Sublime

Negative look ahead with regex is another useful constraint that we can add to our expression. It only matches the left side, if and only if the look ahead doesn't match. The look ahead doesn't consume any characters and has the following syntax:

<left side>(?!<look ahead>)

Example:

<?xml version="1.0"?>
<fruits>
 <a>apple</a>
 <b></b>
 <c>cashew</c>
 <d></d>
</fruits>

From the XML above find all the empty elements and add an attribute empty that is set to true but only matching the opening tag.

Find Replace Comment
<(?<tag>\w*[^>])>(?!(\n|\w)) <$1 empty=”true”> The <left side> is the one highlighted in blue.

The negative <look ahead> is the one highlighted in green.

RegEx Positive Look Ahead with Sublime

Positive look ahead with regex is another useful constraint that we can add to our expression. It only matches the left side, if and only if the look ahead matches. The look ahead doesn't consume any characters and has the following syntax:

<left side>(?=<look ahead>)

Example:

<?xml version="1.0"?>
<fruits>
 <a>apple</a>
 <b></b>
 <c>cashew</c>
 <d></d>
</fruits>

From the XML above find all the empty elements and add an attribute empty that is set to true but only matching the opening tag.

Find Replace Comment
<(?<tag>\w*[^>])>(?=</\k<tag>>) <$1 empty="true"> The <left side> is the one highlighted in blue.

The positive <look ahead> is the one highlighted in green.

Configuring User Level Proxy for Gradle

  1. Create gradle.properties files in the following directory if not yet existing:
     <USER_HOME>/.gradle
  2. Add the following entries for http proxy configuration in the gradle.properties file:
    systemProp.http.proxyHost=<PROXY_HOST>
    systemProp.http.proxyPort=<PROXY_PORT>
    systemProp.http.proxyUser=<PROXY_USERNAME>
    systemProp.http.proxyPassword=<PROXY_PASSWORD>
    systemProp.http.nonProxyHosts=<NON_PROXY_HOSTS>

    Note: <NON_PROXY_HOSTS> is delimited by pipe symbol (e.g. localhost|*.test.net)

    Note: If https proxy configuration is needed use the same entries except that all http will must be replaced with https (e.g. systemProp.https.proxyHost).

« Older posts Newer posts »