Java

Java Subjects

Java 17

Java 11

Java 11 Overview

Java 9

Java Modules

  • Introduction to Modules - https://www.javacodegeeks.com/2023/03/java-modules-an-introduction.html
    • Way of encapsulating project to reduce runtime, explicitly specify dependencies
    • Specify using module-info.java file
    • Special way to build and run using the java commands to indicate it's a module
    • Completely different to maven multi-module which is related to compile time dependencies
      • JPMS modules are to do with runtime dependencies

Javalin framework

An alternative to Spring using Kotlin - aims to be much more lightweight and could be easier to use than Springboot.

JSR 303

Apache StringUtils

Lots of really nice utils for String manipulation (TODO - check the perf)

Java 8 stuff

Java 8 - Loops replaced by streams

Old style loop

public List<Article> getAllJavaArticles() {

      List<Article> result = new ArrayList<>();
      for (Article article : articles) {
          if (article.getTags().contains("Java")) {
              result.add(article);
          }
      }
      return result;

}

Java 8 Style

public List<Article>
getAllJavaArticles() {

    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .collect(Collectors.toList());

}

Example of :: operator

    private void initializeContext() {
      Context = SomeResponse.getStuffList().stream()
          .collect(Collectors.toMap(Stuff::getStuffId, stuff -> GetStuffBuilderContext.createSwaggerStuffId(stuff)));
          .collect(Collectors.toMap(Stuff::getStuffId, GetOfferBuilderContext::createSwaggerStuffId));
    }

Java 8 from Evernote

Articles

Using Optional to avoid NullPointerExceptions, Null Checks etc

public static String safeGreetOptionalWay(RootObject rootObject) {
  return Optional.ofNullable(rootObject)
        .map(r -> r.getFirstLevelObject())
        .map(f -> f.getSecondLevelObject())
        .map(s -> s.getThirdLevelObject())
        .map(t -> t.getName())
        .map(n -> "Hello " + n)
        .orElse("Hey There!");
}
// Gets the first value and flatmaps so we get Optional<String> not Optional<Optional<String>>
public Optional<String> optionalListFirst() {
   return getOptionalList()
      .flatMap(list -> list.stream().findFirst());
}

Optional articles - especially the avoiding anti-patterns

Lambda Expressions

StreamEx library - enhanced streams in java

Dropbox - Tech Docs - Introducing Java 8

Notes -

Some Main Objectives:

  • Tackle verbosity + readability issues in Java e.g. lambdas to reduce boilerplate Streams API - handle data processing -> SQL like syntax
  • Allow exploitation of Multi-core processors Parallel Streams

Features

  • Lambda Expressions -
    • pass pieces of code in a concise way
    • Special syntax "->" e.g. new Thread( () -> System.out.println("Hi") ).start();
  • Method Refs -
    • linked to lambdas, can pass a ref to an existing method of a class - e.g. compareToIgnoreCase()
    • Special syntax ::
  • Streams -
    • Major change to working with Collections
    • Fluent API way of chaining calls
    • Lots of new methods
      • filter
      • sorted
      • reversed
      • map
      • collect
    • linked with Big Data, Map-Reduce etc.
  • Enhanced Interfaces -
    • Default Methods - allow backward compatible Java API changes - e.g. List.sort() with default impl NB - now a form of Multiple inheritance since classes can imp multiple ifaces, Strict Java rules (todo -what rules???)
      • Static Methods e.g. Collection iface and Collections class to provide static utility methods -> now can be in 1 interface
      • New Date and Time API Domain Driven design - new notions of date and time (based on but somewhat different to Joda) Fluent style with chaining. Immutable objects to make them Thread safe and avoid accidental updates
      • CompletableFuture Asynch programming - linked with Streams Improvement of Future class Can compose and process multiple asynch tasks and combine results
      • Optional Allow better modelling when a value can be there or not. Helps avoid NullPointerExceptions - good for nested retrieves and providing alternative values

Streams

NB - not like the network IO streams - concept based on functional programming and map reduce stuff

Stream Examples


// Ordering a collection
List<String> list = Arrays.asList("9", "A", "Z", "1", "B", "Y", "4", "a", "c");
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
sortedList.forEach(System.out::print); // 1 4 9 A B Y Z a c

Eclipse Collections vs Lambdas

NB - Eclipse Collections has some really nice examples of efficient searches, even compared to lambdas

Example 1 - Filter a list (here it's based on finding IError.getType() equal to ErrorType.WARNING)

MutableList<IError> warnings = myResponse.getErrors().select(e ->e.getType().equals(ErrorType.WARNING));

// vs Lambdas
myResponse.getErrors().stream().filter(e -> e.getType().equals(ErrorType.WARNING)).collect(Collectors.toList());

// Example 2 - Check for any occurrence in a list
boolean areThereErrors =
myResponse.getErrors().anySatisfy(e -> e.getType().equals(ERROR));

myResponse.getErrors().stream().anyMatch(e ->
e.getType().equals(ERROR));

Streams with an index

How to have an index i instead of having to use a for loop(int i=0 ….

Streams maps with a lambda with parameters instead of a functional interface method

void toto (String someParam) {
  collectionOfStuff.stream()
              .filter (blah -> blah.getLevels().contains(someParam))
              .map(this::sendTiTi); // can do this if sendTiTi(Blah blah)
              .map(b -> sendTiTi(b, someParam)); // OR can do this if sendTiTi(Blah blah, String someParam)
}

private Blah sendTiTi (Blah blah, String someParam) {
    .....
    return blah;
}

Stream to check for existence of something in a collection

  • Using stream and "anyMatch" to check for the presence of some value or field etc.
  // Example for a protobuf object in java form
  private static boolean hasFieldsToBuild(Builder brandingBuilder) {
    return Builder.getDescriptor()
        .getFields()
        .stream()
        .anyMatch(brandingBuilder::hasField);
  }

Nested Streams

To replace something like this:

C c1 = null;
String name = "name1"
for (A a: listOfAObjects) {
    for (B b: a.getList()) {
        for (C c: b.getPr()) {
            if (c.getName().equalsIgnoreCase(name)) {
                c1= c;
                break;
            }
        }
    }
}

Can do this:


C c1 = listOfAObjects.stream()
        .flatMap(a -> a.getList().stream())
        .flatMap(b -> b.getPr().stream())
        .filter(c -> c.getName().equalsIgnoreCase(name))
        .findFirst()
        .orElse(null);

Can also filter nulls with this:

  .filter(Objects::nonNull)

Stream to join Strings

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Ola Hansen", 21));  ..
  
  
  String names = persons.stream()
    .filter(p -> p.getAge() > 18)
    .sorted((p1, p2) -> p1.getAge() - p2.getAge())
    .map(p -> p.getAge() + ":" + p.getName())
    .collect(Collectors.joining(", "));

Effectively final vs final


public void method() {
    String localVariable = "Local";
    Foo foo = parameter -> {
        String localVariable = parameter;
        return localVariable;
    };
}

Quartz Scheduler

Quartz Scheduler

http://www.quartz-scheduler.org/

TODO - Corrections for their readmes and also add BCC to sendMailJob

Regex

Regex Tester - really handy tool https://www.debuggex.com/

Examples:

  • Match 2 char string alphanumeric CSV, ignoring whitespace -
^(([0-9a-zA-Z]{2},\s*)*([0-9a-zA-Z]{2}))$

Logging in Java

Log4J2 and SLF4J

Log4J2 seems to be the latest incarnation of the java logging "standard" and provides an api + impl and seems to have good java 8 support. SLF4J is still very popular and viewed as an independent way to have a logging api with a lot of features. There are flame wars :)

Here's an example of using log4J2 as the primary api + implementation with a bridge to allow a third party jar using SLF4J to log under the log4J2 config

Logging and Mapped Diagnostic Context MDC

  • https://www.baeldung.com/mdc-in-log4j-2-logback
    • Shows how MDC can be used in Log4J, Log4j2, Slf4j etc.
    • Basic idea is to create a context where we can put information when we have it - e.g. transaction ids etc. and then it can be included in logging messages where we may not have access to the context e.g. handle an error or logging a field value
    • Need to setup and then clean the context, especially when using thread pools or there is a risk of stale data being used.

Further reading:

Spring Framework - TO MOVE

REST API with Async calls in Spring

Java Articles

http://www.intertech.com/Blog/Post/Top-10-Nasty-Java-Bugs.aspx

Java Language

Strings and Immutability

Why are Strings immutable?

A few reasons:

  • String Pool - allows caching of Strings in the String pool
  • Performance - no need to recalculate hashes
  • Thread Safe - can share between different threads without risk of modification

NB - immutable through it's public API. Can still manipulate by reflection.

Thread local

Way of giving threads their own copy of variable without making it local

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

Memory and Garbage Collection

Garbage Collection can be requested but never guaranteed to run. Simplest memory leak example is a static List where the app continually adds items without ever removing them. In this case the objects are allocated but never de-allocated because they are never in a situation where they cannot be referenced.

Memory leak tooling in Java

Finding jars and classes loaded during execution

If you add -verbose:class to the arguments for the JVM for launching, you get a list of the classes loaded during execution and also what jars they come from. Can be very useful for figuring out the dependencies needed at runtime.

Statics

Static properties are class level properties, not unique to an instance.

The static method "override" question pops up sometimes: Basically you can't override, it's a redefinition and the object reference type determines the method called.

Serialization

Method of writing/read objects to or from a stream in order to transfer them to file/transport etc.

  • Serialize to a stream
  • Deserialize to an object

Multiple methods of serialization:

  • Default Protocol - Interface - implements Serializable
  • Customize Default Protocol - Override Object methods - readObject/writeObject
  • Custom Protocol - implements Externalizable (very manual)

transient - mark a property that is not to be serialized.

Example of Simple reading in of an object

try
{
     fis = new FileInputStream(filename);
     in = new ObjectInputStream(fis);
     time = (PersistentTime)in.readObject();
     in.close();
}catch(IOException ex){
    //blah
}

Reading from Standard in using Scanner

link to article on serialization: http://java.sun.com/developer/technicalArticles/Programming/serialization/

File operations

NIO library example for writing to file

// Simple case with some strings and the NIO Files API
Path path = Paths.get("src/main/resources/question.txt"); 
String question = "To be or not to be?";
Files.write(path, question.getBytes());

// More efficient with large files using a bufferedWriter
Path path = Paths.get("src/main/resources/shakespeare.txt");
try(BufferedWriter writer = Files.newBufferedWriter(path, Charset.forName("UTF-8"))){
  writer.write("To be, or not to be. That is the question.");
}catch(IOException ex){
  ex.printStackTrace();
}

Date and Time

Timezone updates for the JDK/JRE

Threading

Thread and sync changes in java 1.5 http://onjava.com/onjava/excerpt/jthreads3_ch6/index1.html

Collections

Collections Tutorial on Sun/Oracle site: http://docs.oracle.com/javase/tutorial/collections/intro/index.html

My notes here - Java Collections

also - estimation of big O notation http://www.dreamincode.net/forums/topic/125427-determining-big-o-notation/

  • Creating a list from a group of objects
  // Java 8
  Arrays.asList(Objects...);

  // Java 9+
  List.of(Objects...);
    // handy snippet
    List<String> result = new ArrayList<String>();
    iterable.forEach(result::add);

Searching

Big O Notation links: http://www.leepoint.net/notes-java/algorithms/big-oh/bigoh.html http://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/

JavaMail

JavaMail with text, html and attachments

http://mlyly.wordpress.com/2011/05/13/hello-world/ http://www.thatsjava.com/java-enterprise/4355/

Testing with Initial Context

Testing with an initialContext outside a container

Basically creating the intial context for JDBC, constants etc.

/**
 - Test classe pour generation de fichier xml de vente avec JaxB.
 - Cette classe utilise un InitialContext pour trouver les chemins vers les fichiers qui sont normalement en web.xml
 - NB - Pour executer il faut ajouter tomcat-juli.jar au classpath du run configuration (qui se trouve dans $TOMCAT_HOME/bin).
 - @author d.costello
 *
 */
public class TestJaxBClient {

    public static void main(String[] args) throws Exception {
        try {
            // Create initial context
            System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
            System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
            InitialContext ic = new InitialContext();

            ic.createSubcontext("java:");
            ic.createSubcontext("java:comp");
            ic.createSubcontext("java:comp/env");

            ic.bind("java:comp/env/ressRetailProOutDirClient", "");
            ic.bind("java:comp/env/ressRetailProOutDirPurchase", "");

            TestJaxBClient testJaxB = new TestJaxBClient();
        }catch(Exception e){
            // TODO
        }
    }
}

Web Stuff - JSP, Servlet etc

good explanation on WebApp and JSTL/JSP versions: http://www.mularien.com/blog/2008/04/24/how-to-reference-and-use-jstl-in-your-web-application/

Ajax Response - JSON

  • Jackson
  • GSON - google version of JSON

JSP

Code for importing an external file into a JSP Page

<c:import url="http://www.someSite.net/RssReader/GoogleRssReader/RssHelloWorldV4.html"></c:import>

Spring Framework

Spring with Groovy

If you want to wire in a Groovy class as a Bean, you have to have it implement a Java interface, you use the interface name in the Java class that wants to use it, and your Groovy Bean gets declared in the App Context using the special Groovy syntax.

http://forum.springsource.org/showthread.php?35351-Autowiring-does-not-work-with-Groovy

Spring Articles

Spring MVC

Resource mapping

<mvc:resources mapping="/css/**" location="/resources/css/"/>
JSP Displaying JSON List

http://stackoverflow.com/questions/20756970/how-to-display-json-object-in-jsp http://stackoverflow.com/questions/20756970/how-to-display-json-object-in-jsp

Spring MVC and Ajax

http://spring.io/blog/2010/01/25/ajax-simplifications-in-spring-3-0/

Patterns in Spring

http://stackoverflow.com/questions/755563/what-are-the-design-patterns-which-used-in-spring-framework\#!

J2EE

http://java.sun.com/javaee/5/docs/tutorial/doc/bnbly.html

This is a good introduction to EJB3 using Netbeans and Glassfish which creates a simple stateless session bean and connects to it using a Servlet and a client. http://wiki.netbeans.org/CreatingEJB3UsingNetbeansAndGlassfish

This is a fuller example http://netbeans.org/kb/docs/javaee/javaee-entapp-ejb.html

Transactions in J2EE

Q&A from Sun site http://java.sun.com/blueprints/qanda/transaction_management/index.html

JNDI

Sun Tutorial for JNDI (TODO) http://java.sun.com/products/jndi/tutorial/trailmap.html

JAXB

To get some nice objects that you can marshall or unmarshall here are some tips.

Generate an XSD if you just have a plain XML example file

$/Dev/Java/Libraries/xmlbeans-2.5.0/bin/inst2xsd test01.xml

Use your XSD along with a binding file to generate some Java objects via the XJC compiler

XJC is included with the Java6 install in the /bin directory. It can be invoked on the command line but can also (using an extra jar) be incorporated into an ANT task.

  $xjc -b binding.xml -p com.yourcompany.generated test_0.xsd

Marshal unmarshall in JaxB

This will give you a nice xml string output from a JaxB object.


/**
 * Marshall input object to a formatted XML String
 */
protected <T> String marshal(T input) throws JAXBException {
    StringWriter writer = new StringWriter();

    JAXBContext jc = JAXBContext.newInstance(input.getClass());
    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.marshal(input, writer);
    return writer.toString();
}

If for some reason we don't have a full XML schema object stack from the root, we can still marshal. For example you only want to marshal part of a jaxb object.

  //If we DO NOT have JAXB annotated class
  JAXBElement<Employee> jaxbElement = new JAXBElement<Employee>(new QName("", "employee"), Employee.class, employeeObj);
        
  jaxbMarshaller.marshal(jaxbElement, System.out);

Date formatting in JaxB XML

  // DatatypeFactory comes from javax.xml.datatype (same package as XMLGregorianCalendar)

  // Build directly from a date
  LocalDate localDate = LocalDate.of(2019, 4, 25);  
  XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(localDate.toString());

  // Build from a formatted string
  String localDate2 = LocalDate.now().plusDays(30).format(DateTimeFormatter.ISO_DATE);
  XMLGregorianCalendar departureDateXmlCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(localDate2);

JAX-RS

Server side - build a JSON Response body

@GET
@Path("/pojo")
public Response getPojoResponse() {

    Person person = new Person("SomeName", "SomePlace");

    return Response
      .status(Response.Status.OK)
      .entity(person)
      .build();
}

Client side - Reading or Printing a JSON Response body

  import jakarta.ws.rs.core.Response;

  Response response = //... get the response object

  // Optional - Buffer entity if you want to read response body AND subsequently readEntity to object, otherwise it will fail due to the stream being closed.
  // This is specific to when you want to read response body as say a string and then later read the entity to an object
  response.bufferEntity(); 
  
  // read response body
  String body = response.readEntity(String.class);

  // After reading with readEntity, can use getEntity to retrieve the cached object
  Object obj = response.getEntity();

  // Could also readEntity to a class


(See also the Rest page in architecture)

Asynchronous Programming - Completable Futures & Futures

Involves using Completable Futures and Futures to handle asynchronous programming.

thenApply vs thenCompose

  • Equivalent to map and flatmap
    • map - [1,2,3,4]
    • flatmap - [(1,2), (3,4)]
    • apply - use when a single completable future
    • compose - when a nested completable future

Exception handling

Mocking errors in CompletableFuture

CompletableFuture<Long> future = new CompletableFuture<>();
future.completeExceptionally(new Exception("HTTP call failed!"));

Mockito.when(mockClient.getSize())
        .thenReturn(future);

Lombok

Javadoc

Referencing methods in javadoc


class SomeClass {
  /**
   * REF a method in the same class
   * Also, check the {@link #move() Move} method for more movement details.
   */
  public void walk() {}

  public void move() {}

  /**
   * REF a method in another package and class (NB - can omit the package if same)
 * Also consider checking {@link com.baeldung.sealed.classes.Vehicle#Vehicle() Vehicle} 
 * constructor to initialize vehicle object.
 */
public void goToWork() {

}
}

Application Servers

IDEs

Intellij

  • if you have issues with "sticky" mouse selection and right-click not working, it might be because you touched the touchscreen of the laptop at the same time as using the mouse/trackpad. Focus on the Intellij window and then touch the touchscreen again to resolve the issue.