Vortrag-Bad-Honnef/Vortrag/main.tex

455 lines
15 KiB
TeX
Raw Normal View History

2024-05-20 21:32:06 +00:00
\documentclass[aspectratio=43]{beamer}
2024-04-21 12:38:15 +00:00
\usepackage{lmodern} % Add the lmodern package to fix missing font shapes
2024-04-16 20:07:51 +00:00
\usepackage{beamerthemeDHBW} % Include the package
2024-04-19 21:43:21 +00:00
\usepackage[overlay, absolute]{textpos}
2024-04-16 20:07:51 +00:00
\usepackage{bookmark}
2024-04-19 21:43:21 +00:00
\usepackage{pgfplots}
2024-05-20 21:32:06 +00:00
\usepackage[ngerman]{babel}
\usepackage{tikz}
2024-04-21 12:38:15 +00:00
\usepackage{amssymb} % Add the amssymb package to fix missing font shape
2024-04-19 21:43:21 +00:00
\usepackage{listings}
2024-05-20 21:32:06 +00:00
\usepackage{tcolorbox}
2024-04-19 21:43:21 +00:00
\newcommand{\internetadresse}{https://www.dhbw-stuttgart.de}
\pgfplotsset{compat=1.18}
\lstset{
basicstyle=\ttfamily\scriptsize,
2024-05-20 21:32:06 +00:00
keywordstyle=\bfseries,
commentstyle=\color{green!50!black},
2024-04-27 15:06:02 +00:00
escapeinside={(*@}{@*)},
2024-04-19 21:43:21 +00:00
numbers=left,
numberstyle=\tiny\color{gray},
frame=single,
2024-05-20 21:32:06 +00:00
backgroundcolor=\color{lightgray!10},
2024-04-19 21:43:21 +00:00
showspaces=false,
showstringspaces=false,
showtabs=false,
breaklines=true,
tabsize=4
2024-04-19 21:43:21 +00:00
}
2024-04-16 20:07:51 +00:00
%Information to be included in the title page:
\title{Java-TX Compiler in Java-TX}
2024-05-20 21:32:06 +00:00
\subtitle{Bad Honnef 2024}
2024-04-16 20:07:51 +00:00
\author{Julian Schmidt}
\institute{DHBW Stuttgart}
\date{2024}
\usetheme{DHBW}
\begin{document}
\maketitle
2024-04-27 15:06:02 +00:00
\begin{frame}[fragile]
\frametitle{Motivation I}
2024-04-21 12:38:15 +00:00
\begin{itemize}
\item Welche Features fehlen noch in Java-TX?
\item Welche Bugs gibt es?
\item Vorteile/Nachteile zu Java in der Praxis
2024-05-20 21:32:06 +00:00
\item Wie performant ist Java-TX für \glqq{}größere\grqq{} Projekte?
2024-04-21 12:38:15 +00:00
\end{itemize}
2024-04-27 15:06:02 +00:00
\begin{visibleenv}<2>
\begin{table}
\begin{tabular}{ l | c | c }
Language & files & code \\
\hline \hline
Java & 247 & 17958 \\
ANTLR Grammar & 2 & 771 \\
\hline
SUM & 249 & 18729 \\
2024-05-20 21:32:06 +00:00
\end{tabular}
2024-04-27 15:06:02 +00:00
\end{table}
\end{visibleenv}
2024-04-19 21:43:21 +00:00
\end{frame}
2024-04-19 21:43:21 +00:00
\begin{frame}
\frametitle{Motivation II}
2024-04-19 21:43:21 +00:00
\begin{center}
2024-04-21 12:38:15 +00:00
\begin{tikzpicture}[scale=3]
2024-04-27 15:06:02 +00:00
\draw<2> (1,0) -- (0,0) -- (0,1) -- (3,1) -- (3,0) -- (2,0) -- (2, -1.1) -- (1, -1.1) -- cycle;
\node<2> at (0.5, 0.5) {JTX};
\node<2> at (1.5, -0.55) {JTX};
\node<2> at (2.5, 0.5) {BC};
2024-04-21 12:38:15 +00:00
\draw (3.1,-1.1) -- (2.1,-1.1) -- (2.1,-0.1) -- (5.1,-0.1) -- (5.1,-1.1) -- (4.1,-1.1) -- (4.1, -2.2) -- (3.1, -2.2) -- cycle;
\node at (2.6, -0.6) {JTX};
\node at (3.6, -1.6) {JAVA};
\node at (4.6, -0.6) {BC};
\end{tikzpicture}
\end{center}
2024-04-19 21:43:21 +00:00
\end{frame}
2024-05-20 21:32:06 +00:00
\begin{frame}[fragile]
\frametitle{JavaTX}
\begin{itemize}
\item Programmiersprache basierend auf Java 8
\item Globale Typinferenz
\item Lambda-Ausdrücke sind getypt
\item Überladung von Funktionstypen
\item Automatisches Überladen von Funktionen
\item Automatisches generieren von Generics
\item Autoboxing von primitiven Datentypen
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Vergleich Sourcecode Java - Java-TX}
\begin{columns}[T]
\begin{onlyenv}<0->
\begin{column}{0.5\textwidth}
\begin{lstlisting}[language=java]
public class FunNClass extends ClassOrInterface {
2024-05-20 21:32:06 +00:00
private static (*@\alert<2,4>{GenericDeclarationList}@*)
createGenerics(
(*@\alert<2,4>{List<GenericRefType>}@*) funNParams) {
var generics =
new ArrayList<(*@\alert<2>{GenericTypeVar}@*)>();
for ((*@\alert<2>{GenericRefType}@*) param : funNParams) {
generics.add(...);
}
return new GenericDeclarationList(generics, new NullToken());
}
}
\end{lstlisting}
\end{column}
\end{onlyenv}
\begin{column}{0.5\textwidth}
2024-05-20 21:32:06 +00:00
\begin{onlyenv}<-2>
\begin{lstlisting}[language=java, backgroundcolor=\color{red!10}]
public class FunNClass extends ClassOrInterface {
2024-05-20 21:32:06 +00:00
private static
createGenerics(
funNParams) {
2024-05-20 21:32:06 +00:00
var generics =
new ArrayList<>();
2024-05-20 21:32:06 +00:00
for (param : funNParams) {
generics.add(...);
}
return new GenericDeclarationList(generics, new NullToken());
}
}
\end{lstlisting}
\end{onlyenv}
2024-05-20 21:32:06 +00:00
\begin{onlyenv}<3->
\begin{lstlisting}[language=java, backgroundcolor=\color{green!10}]
public class FunNClass extends ClassOrInterface {
2024-05-20 21:32:06 +00:00
private static (*@\alert<4>{GenericDeclarationList}@*)
createGenerics(
(*@\alert<4>{Iterable<? extends GenericRefType>}@*) funNParams) {
ArrayList<GenericTypeVar> generics =
new ArrayList<GenericTypeVar>();
for (GenericRefType param : funNParams) {
generics.add(...);
}
2024-05-20 21:32:06 +00:00
return new GenericDeclarationList(generics, new NullToken());
}
}
\end{lstlisting}
2024-05-20 21:32:06 +00:00
\end{onlyenv}
\end{column}
2024-05-20 21:32:06 +00:00
\end{columns}
\end{frame}
2024-05-20 21:32:06 +00:00
\begin{frame}[fragile]{Aufbau der Umgebung I}
\begin{enumerate}
\item Compiler soll sukzessive in Java-TX umgeschrieben werden
\item Umgebung mit .java und .jav Dateien
\item Ziel: Auf JVM ausführbare .class Dateien
\end{enumerate}
\end{frame}
2024-04-19 21:43:21 +00:00
\begin{frame}[fragile]
\frametitle{Aufbau der Umgebung II - make}
Erster Ansatz mit make:
2024-04-21 12:38:15 +00:00
\begin{lstlisting}
2024-04-19 21:43:21 +00:00
# Use find to locate all .java and .jav files recursively
JAVASOURCES := $(shell find $(SRCDIR) -name '*.java')
JAVSOURCES := $(shell find $(SRCDIR) -name '*.jav')
2024-04-19 21:43:21 +00:00
# Convert .java/.jav files to .class files with the same directory structure
JAVACLASSES := $(patsubst $(SRCDIR)/%.java,$(DESTDIR)/%.class,$(JAVASOURCES))
JAVCLASSES := $(patsubst $(SRCDIR)/%.jav,$(DESTDIR)/%.class,$(JAVSOURCES))
# Rule for compiling .jav files
$(DESTDIR)/%.class: $(SRCDIR)/%.jav
java -jar $(JTX) -d "$(dir $@)" -cp "$(SRCDIR):$(DESTDIR):target/dependencies/" $<
# Rule for compiling .java files
$(DESTDIR)/%.class: $(SRCDIR)/%.java
$(JC) -nowarn -d $(DESTDIR) -cp "$(SRCDIR):$(DESTDIR):target/dependencies/*" $(JFLAGS) $<
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Aufbau der Umgebung III}
2024-04-19 21:43:21 +00:00
Probleme:
\begin{enumerate}
2024-05-20 21:32:06 +00:00
\item javac compiliert und trackt Änderungen von Abhängigkeiten automatisch
\item javac ist sehr langsam wenn für jede Datei einzeln aufgerufen (mehrfache Compilierungen + JVM overhead)
2024-04-19 21:43:21 +00:00
\end{enumerate}
2024-05-20 21:32:06 +00:00
\begin{columns}[T]
2024-04-21 12:38:15 +00:00
\begin{column}{0.5\textwidth}
\begin{lstlisting}
2024-04-19 21:43:21 +00:00
javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java
javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java
...
javac src/main/java/Main.java
\end{lstlisting}
$\sim{}$5min Compilerzeit
2024-04-21 12:38:15 +00:00
\end{column}
\begin{column}{0.5\textwidth}
\begin{lstlisting}
2024-04-19 21:43:21 +00:00
javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java ... src/main/java/Main.java
\end{lstlisting}
$\sim{}$2sec Compilerzeit
2024-04-21 12:38:15 +00:00
\end{column}
\end{columns}
2024-04-19 21:43:21 +00:00
\end{frame}
\begin{frame}[fragile]{Aufbau der Umgebung IV - compile script}
2024-04-19 21:43:21 +00:00
\begin{enumerate}
2024-05-20 21:32:06 +00:00
\item Lese alle Sourcecode Dateien (*.jav, *.java)
\item Filtere die Dateien, die neu compiliert werden müssen
\item Rufe den Compiler einmal mit allen Sourcefiles als Argumente auf
\lstinline!javac -d "$DESTDIR" -cp "$SRCDIR:$DESTDIR:target/dependencies/*" $JAVAC_FLAGS "${JAVA_CHANGED[@]}"!
2024-04-19 21:43:21 +00:00
\end{enumerate}
2024-05-20 21:32:06 +00:00
% \begin{enumerate}
% \item Suche rekursiv alle .java und .jav Dateien im Quellverzeichnis und speichere sie jeweils in einer Liste
% \item Überprüfe für jede Quelldatei, ob die zugehörige .class Datei im Zielverzeichnis existiert und ob die Zieldatei neuer als die Quelldatei ist
% \begin{itemize}
% \item Wenn ja, gehe weiter zur nächsten Datei
% \item Wenn nein, füge die Quelldatei zur Liste der zu kompilierenden Dateien hinzu
% \end{itemize}
% \vspace*{-\baselineskip}
% \item Rufe den Java-TX Compiler mit allen Dateien in der jav-Liste als Argumente auf
% \lstinline{java -jar $JAVATX_COMPILER_PATH -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/" ${JAV_CHANGED[@]}}
% \item Rufe den javac Compiler mit allen Dateien in der java-Liste als Argumente auf
% \lstinline{javac -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/*" $JAVAC_FLAGS ${JAVA_CHANGED[@]}}
% \end{enumerate}
2024-04-16 20:07:51 +00:00
2024-04-21 12:38:15 +00:00
\end{frame}
2024-05-20 21:32:06 +00:00
% \begin{frame}[fragile]{Bugübersicht}
% \begin{center}
% \begin{tikzpicture} \begin{axis}[ ybar, enlargelimits=0.15, legend style={at={(0.
% 5,-0.3)}, anchor=north,legend columns=-1}, ylabel={amount}, symbolic x
% coords={open,closed}, xtick=data, nodes near coords, nodes near coords
% align={vertical}, width=0.7\textwidth, height=10cm, bar width=2cm]
% \addplot coordinates {(open,1) (closed,25) };
% \addplot coordinates {(open,3) (closed,18) };
% \legend{Bugs,Feature Requests}
% \end{axis}
% \end{tikzpicture}
% \end{center}
% \end{frame}
\begin{frame}[fragile]{Primitive Typen in Java-TX}
\begin{itemize}
\item Java erlaubt neben Referenztypen auch primitive Datentypen (int, boolean, ...)
\item Java-TX erlaubt primitive Datentypen zwar im Quellcode, wandelt diese aber in die korrespondierende Wrapperklasse um (Integer, Boolean, ...)
\end{itemize}
2024-05-20 21:32:06 +00:00
\begin{columns}[T]
\begin{column}{0.5\textwidth}
\begin{lstlisting}[language=java]
int a = 10;
boolean b = true;
float c = 10.0f;
\end{lstlisting}
\end{column}
\begin{column}{0.5\textwidth}
2024-05-20 21:32:06 +00:00
\begin{lstlisting}[language=java]
Integer var1 = null;
var1 = 10;
Boolean var2 = null;
var2 = true;
Float var3 = null;
var3 = 10.0F;
\end{lstlisting}
\end{column}
\end{columns}
\end{frame}
2024-05-20 21:32:06 +00:00
\begin{frame}[fragile]{Überschreiben von Methoden II}
\begin{itemize}
2024-05-20 21:32:06 +00:00
\item In Java: Methoden nicht anhand von Rückgabewert überschreibbar
\end{itemsize}
\begin{lstlisting}[language=java]
public class Bar {
int foo(Object obj){return 0;}
boolean foo(Object obj){return false;}
}
\end{lstlisting}
\begin{lstlisting}
Bar.java:3: Fehler: Methode foo(Object) ist bereits in Klasse Bar definiert
boolean foo(Object obj){return false;}
^
\end{lstlisting}
\begin{itemize}
\item Aber: Generell auf JVM lauffähig
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Überschreiben von Methoden II}
\begin{itemize}
\item Überschreiben von Java Methoden mit primitiven Datentypen als Parameter funktionierte nicht
\end{itemize}
\vspace*{-\baselineskip}
\begin{lstlisting}[language=java]
public boolean equals(Object obj);
\end{lstlisting}
2024-05-20 21:32:06 +00:00
\begin{lstlisting}[language=java, backgroundcolor=\color{red!10}]
public class Foo {
equals(Object o){
return false;
}
}
\end{lstlisting}
\begin{lstlisting}[language=java]
public class Foo {
public Foo() {}
Boolean equals(Object var1) {
return false;
}
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Überschreiben von Methoden III}
\begin{itemize}
\item Lösung: Wenn Methodensignatur eines Supertyps sich nur in primitiven-/Wrapper-Datentypen unterscheidet, werden Typen vom Supertyp in Subtyp substituiert
\end{itemize}
2024-05-20 21:32:06 +00:00
\begin{lstlisting}[language=java, backgroundcolor=\color{red!10}]
public class Foo {
equals(Object o){
return false;
}
}
\end{lstlisting}
\begin{lstlisting}[language=java]
public class Foo {
public Foo() {}
boolean equals(Object var1) {
return false;
}
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces I}
\begin{itemize}
\item In Java haben Lambda Ausdrücke als Target Type ein funktionales Interface z.B. java.util.function.Function
\begin{lstlisting}[language=java]
Function<Integer, Integer> func = x -> x*2;
\end{lstlisting}
\item Java-TX unterstützt echte Funktionstypen
2024-05-20 21:32:06 +00:00
\begin{lstlisting}[language=java, backgroundcolor=\color{red!10}]
var func = x -> x*2;
2024-05-20 21:32:06 +00:00
func: Fun1$$<Integer, Integer>
\end{lstlisting}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces II}
\begin{itemize}
2024-05-20 21:32:06 +00:00
\item Java ist nominal typisierte Sprache
\item Problem: Lambda Ausdrücke haben in Java-TX einen FunN\$\$ Typ (für N = \#Parameter)
\item Aber: Java Bibliotheken wie Stream erwarten verschiedene funktionale Interfaces
2024-05-20 21:32:06 +00:00
\item Daher: Lambda Ausdrücke müssen je nach Kontext erwartetes funktionales Interface als Target Typ haben
\end{itemize}
\begin{lstlisting}[language=java]
public class Main {
main() {
List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5));
return list.stream().map(x -> x*2).toList();
}
2024-05-20 21:32:06 +00:00
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces III}
\begin{lstlisting}[language=java]
<R> Stream<R> map(Function<? super T, ? extends R> var1);
\end{lstlisting}
\begin{lstlisting}[language=java]
public interface Function<T, R> {
R apply(T var1);
}
\end{lstlisting}
\vspace*{\baselineskip}
\begin{itemize}
2024-05-20 21:32:06 +00:00
\item Eigentlich würde Java-TX \lstinline[basicstyle=\normalsize]|Fun1$$<Integer, Integer>| inferieren
\item Aber: Stream.map erwartet \lstinline[basicstyle=\normalsize]|Function<? super T, ? extends R>|
\end{itemize}
\begin{lstlisting}[language=java]
...
3: invokedynamic #41, 0 // InvokeDynamic #0:apply:(LFoo;)LFun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$;
//Invalid Bytecode
5: invokeinterface #45, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
...
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces IV}
\begin{lstlisting}[language=java]
...
50: invokedynamic #60, 0 // InvokeDynamic #0:apply:(LFoo;)Ljava/util/function/Function;
55: invokeinterface #66, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
...
\end{lstlisting}
\end{frame}
\begin{frame}{Fazit}
Vorteile:
\begin{itemize}
\item Programmierer muss weniger Typen explizit angeben
\item Funktionstypen erlauben übersichtlichere Subtypisierung von anonymen Funktionen als Java
\end{itemize}
Nachteile:
\begin{itemize}
2024-05-20 21:32:06 +00:00
\item (Alle verwendeten/berückstichtigten Typen müssen manuell importiert werden) \\
\(\rightarrow\) Der Programmierer muss schon wissen, welche Typen in Frage kommen
2024-05-20 21:32:06 +00:00
\item Es ist möglich, dass ein ungewünschter Typ inferiert wird
\item Aktuell begrenzte Sprachfeatures \& vermutlich einige Bugs
\end{itemize}
2024-05-20 21:32:06 +00:00
\end{frame}
\begin{frame}{Fazit}
Weg ist noch weit ... \\
Aktuell $\sim{}3\%$ der Java Dateien in Java-TX übersetzt
\begin{center}
\begin{tikzpicture} \begin{axis}[ ybar, enlargelimits=0.15, legend style={at={(0.
5,-0.1)}, anchor=north,legend columns=-1}, ylabel={amount}, symbolic x
coords={open,closed}, xtick=data, nodes near coords, nodes near coords
align={vertical}, width=0.7\textwidth, height=10cm, bar width=2cm]
\addplot coordinates {(open,1) (closed,25) };
\addplot coordinates {(open,3) (closed,18) };
\legend{Bugs,Feature Requests}
\end{axis}
\end{tikzpicture}
\end{center}
\end{frame}
\end{document}