Java

…little Java stuff worth to write down… (because every time I use it I have already forgotten the details…)

  1. Java little stuff
    1. the REPL jshell
    2. maven
    3. gradle troubles
    4. class file compatibility
  2. IntelliJ Stuff for a lost Eclipse User
  3. Java Stream stuff
  4. JPA Stuff
  5. Serializer- and Marshaller-Stuff
  6. Java XPath Stuff
  7. Testing Stuff
  8. Framework-Blueprints
  9. Installer
    1. Java auf macOS
  10. WebApp with dirty JavaScript Frontend
    1. Quick and dirty Json-Load:
    2. Quick and dirty Intercooler-Stuff:
    3. Quarkus Backend

Java little stuff

the String:

//Number: 
String.format("(%f, %f)", x,y); 
String.format("Upload total: %.2f Stunden%n", minuten / 60.0); 
String.format("alles neu, zum  %d. Mal!", n); 

//String: 
String.format("Zone: id: %s, usage: %s, geometry: %s", id, usage, polyLine.toString()); 

shebang support

#!/usr/bin/java --source 11
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hallo Java shebang");
    }
}

find files

File directory = new File("rschumm/");

Optional<Path> foundFile = Files.find(
        directory.toPath(), 
        3,
        (path, basicFileAttributes) -> path.toFile().getName().matches("blabla.*.yml")
        )
.sorted(Comparator.comparing(Path::getFileName))
.findFirst(); 

quick File as String:

String s = Files.lines(Paths.get("jekyll.md")).collect(Collectors.joining()); 

very quick and dirty templating find- and replace

String template = Files.lines(Paths.get("../nfs/pv-nfs.yml")).collect(Collectors.joining("\n")); 
String out = template.replaceAll("0001", ""+i).replaceAll("general", "general/"+i); 	
Files.write(Paths.get("pv"+i+".yml"), out.getBytes(), StandardOpenOption.CREATE); 

Arrays Stuff:

Coordinate[] coordinates = new Coordinate[] {
    new Coordinate(1.0 , 1.0), 
    new Coordinate(1.0 , 100.0), 
    new Coordinate(100.0 , 100.0), 
    new Coordinate(100.0 , 1.0), 
    new Coordinate(1.0 , 1.0), 		                                            
}; 

//List to Array: 
tat.labels.toArray(new String[0])

//Array toString: 
Arrays.toString(labels))

Generics Stuff:

Room and Segement extends Space

List<Room> rooms = ...
List<Segment> segments = ...

// List<Room> is not instance of List<Space>, but List<? extends Space<?>>

public void doSomethingWithSpaces(List<? extends Space<?>> spaces) { ... 

the thing with resources:

getClass().getClassLoader().getResource("MainWindow.fxml")

…sometimes withoug getClassLoader(), sometimes with full path src/main/test/resources/..., e.g.

the REPL jshell

Read–eval–print loop

jshell
/open File.java
/symbols 
jshell> Kegel k1 = new Kegel(1, 2);
k1 ==> r: 1.00 h: 2.00

maven

[luna:~] rschumm% mvn dependency:get -DgroupId=org.mariadb.jdbc -DartifactId=mariadb-java-client -Dversion=2.7.0

gradle troubles

upgrade gradle:

rschumm@kyburg  % gradle wrapper --gradle-version 7.6 

Versions: Gradle Compatibility Matrix

VSCode:

"java.import.gradle.java.home": "/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home"

Specifies the location to the JVM used to run the Gradle daemon. see Doku

class file compatibility

Java Class File Version Numbers: see Oracle and Wiki

Gradle Compatibility Matrix

IntelliJ Stuff for a lost Eclipse User

no, there is no Workspace. Every Project is in a new Window.

JavaDoc hover: press ctrl-q, ctrl-j,alt-space
there is no context-menu for Type Hierarchy: press ctrl-h to open the Hierarchy View
the magic is ⌘-1 / cmd-1 is now ⎇-⮐ / alt-enter

Java Stream stuff

Collect To List:

List<Stuff> stuffInCar = internalStuffs.stream().filter(d -> car.contains(d)).collect(Collectors.toList()); 
List<Stuff> stuffInCar = internalStuffs.stream().filter(car::contains).collect(Collectors.toList()); 
... .toArray(int[]::new); 
... .toArray(String[]::new)

Mapping stuff:

List<Room> roomsWithin = rooms.stream().filter(zone::contains).collect(Collectors.toList()); 
zone.connectAllRooms(roomsWithin);
// ==> terminating map 
internalDevices.stream().filter(segment::contains).forEach(segment::connectDevice); 

nested collection Mapping:

public static List<Eintrag> extractEinträge(List<Tag> tage){
    return tage.stream()
        .flatMap(tag -> 
            tag.taten.stream()
                .map(t -> new Eintrag(t, tag.extractDatum()))
        )
        .collect(Collectors.toList()); 
}

Collect to Array:

Coordinate[] coordinates = points.stream().map(p -> new Coordinate(p.x , p.y)).toArray(Coordinate[]::new);

Nice formatted List of Strings Representations:

public static String eintrageToString(Stream<Tag> tage) {
    return extractEintrage(tage)
    .map(Eintrag::toString)
    .collect(Collectors.joining("\n* ", "* ", "")); 
}

JPA Stuff

@ElementCollection
public List<String> labels;

Serializer- and Marshaller-Stuff

Jackson Json Object Mapper:


public static void writeJson(File f, MyModel i)
    throws JsonGenerationException, JsonMappingException, IOException {
  ObjectMapper mapper = new ObjectMapper();
  mapper.enable(SerializationFeature.INDENT_OUTPUT);
  mapper.writeValue(f, i);
}

public static MyModel readJson(File f) throws JsonParseException, JsonMappingException, IOException {
  ObjectMapper mapper = new ObjectMapper();
  // TODO validate to Schema 
  return mapper.readValue(f, MyModel.class); 
}


// for yaml file that contains a List of Objects (no wrapper object): 

private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());

public List<Tag> readYaml() throws IOException {
  List<Tag> tage = mapper.readValue(file, new TypeReference<List<Tag>>(){} );
  return tage; 
}


JAXB Marshaller:


public void marshall(File file) throws Exception {
  JAXBContext context = JAXBContext.newInstance(MyModel.class);
    Marshaller mar= context.createMarshaller();
    mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    
    mar.marshal(getMyModel(), file); 
}

JAXB Schema Class Generator


<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jaxb2-maven-plugin</artifactId>
  <version>2.5.0</version>
  <executions>
    <execution>
      <id>xjc</id>
      <goals>
        <goal>xjc</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <xjbSources>
      <xjbSource>src/main/resources/global.xjb</xjbSource>
    </xjbSources>
    <sources>
      <source>src/main/resources/schema/mySchema.xsd</source>
    </sources>
    <!-- <outputDirectory>${basedir}/src/main/java</outputDirectory> -->
    <clearOutputDir>false</clearOutputDir>
  </configuration>
</plugin>


JAXB Dependencies

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.1</version>
</dependency>

<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>2.3.1</version>
</dependency>
<!-- JAXB needs javax.activation module (jdk9) -->
<dependency>
  <groupId>javax.activation</groupId>
  <artifactId>javax.activation-api</artifactId>
  <version>1.2.0</version>
</dependency>

Java XPath Stuff

<dependency>
  <groupId>commons-jxpath</groupId>
  <artifactId>commons-jxpath</artifactId>
  <version>1.3</version>	    
</dependency>

n.B. Model must conform to JavaBeans etc. - public variables will not work.

Room room6136 = (Room) JXPathContext.newContext(project).getValue("site/buildings/storeys/rooms[@name='6136']"); 

Testing Stuff

Hamcrest:

<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-all</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>
import static org.hamcrest.Matchers.*; 

assertThat(blabla.getDescription().getValue(), containsString("6136"));

Framework-Blueprints

Rest-Client UniRest - super easy Rest-Client
Rest-assured used by Quarkus
Database Migration flyway
Spark Java WebApp Framework
HTML Parser jsoup
Json Parsing: Jackson or Gson cf hier Yaml Parsing: Jackson, cf Studrepos Example
git access: cf ebenda.

Installer

I recommend Zulu

Java auf macOS

die JDK sind hier:

/Library/Java/JavaVirtualMachines

Install:

tar xf openjdk-14.0.2_osx-x64_bin.tar.gz
sudo mv jdk-14.0.2.jdk /Library/Java/JavaVirtualMachines/
/usr/libexec/java_home

Auf unbekannte magische Weise nimmt macOS automatisch die neuste Version.

WebApp with dirty JavaScript Frontend

Quick and dirty Json-Load:

 <script src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script>

///... 

<script>

function load(){
  $.ajax({
    url: '/hallo/logbuch',
    type: 'GET',
    success: function (response) {
        var trHTML = '';
        $.each(response, function (i, item) {
            trHTML += '<tr><th scope="row">' + item.id + '</th><td>' + item.text + '</td></tr>';
        });
        $('#nt').empty();
        $('#nt').append(trHTML);
    }
  });
}

load(); 

</script>

Quick and dirty Intercooler-Stuff:


<script src="https://intercoolerjs.org/release/intercooler-1.2.2.js"></script>

...  


<form>
    <div class="input-group">
      <input type="text" class="form-control" placeholder="Nachricht an Rémy" aria-label="Input group example" aria-describedby="btnGroupAddon" name="textinput">
      <button type="submit" class="btn btn-primary btn-default" ic-post-to="/hallo/sali" ic-target="#nachricht" ic-on-success="load();">
        Click Me!
      </button>
    </div>
</form>

Quarkus Backend

@POST
@Transactional
@Produces(MediaType.TEXT_PLAIN)
@Path("/sali")
public String saliPost(@FormParam("textinput") String name) {
    Message message = new Message();
    message.text = name;
    message.date = LocalDate.now();
    message.persist();
    return service.sagHallo(name);
}

writing out with OutputStream of type StreamingOutput:

@GET
@Produces("application/x-step")
@Path("/dummy")
public Response dummy() throws IOException {
  Project dummyProject = new DummyProjectBuilder().dummyIfcProject; 
  IfcModel ifcModel = StepMarshaller.mapFromInternal(dummyProject); 
  StreamingOutput streamingOutput = output -> ifcModel.writeStepFile(output);
  return Response.ok(streamingOutput, "application/x-step").header("content-disposition","attachment; filename = dummy.ifc").build(); 
}

zurück zum Seitenanfang