*************************
Z półki Interop
[ http://www.janetdev.org/ ]
czyli -> implementacja Javy 5 (JDK i JRE) dla .NET
powiedzmy, że jest to odpowiednik J# .NET (wydawanego kiedyś przez Microsoft)
… i jestem w trakcie testów, jak dobrze pójdzie to w ciagu
tygodnia będę mógł mówić o sukcesie w postaci skompilowanego
serwera Jetty,
Zestaw zawiera zarówno biblioteki klienckie, jak i typowe
narzędzia deweloperskie, czyli kompilator javac.
Krótko ujmując – możliwość skompilowania projektów napisanych
w javie (rozumiemy to jako czystą javę bez odwołań do bibliotek natywnych) do kodu rozumianego przez biblioteki .NET
I się zaczęło.
Pobranie JDDK nie nastręczało problemów. Instalacja również,
chociaż konieczność wykorzystania konta z uprawnieniami administracyjnymi, gdy i tak samodzielnie trzeba niektóre kroki wykonać przy instalacji SDK
(np.: ustawienie zmiennej systemowej JANET_INSTALL)
http://www.janetdev.org/ManualJaNETSEInstallation/tabid/91/Default.aspx
Nauczony doświadczeniem nie korzystałem ze ścieżki docelowej
zawierającej spacje … od taka porada, że niektóre narzędzia
słabo sobie z tym radzą.
Folder instalacyjny:
G:\zainstalowane\dotnet\janetse-jddk
Folder z narzędziami typu kompilator (javac)
G:\zainstalowane\dotnet\janetse-jddk\jdk\bin
Instalacja zakończona.
Używanie kompilatora javac bez dodatkowych narzędzi jest mówiąc krótko, czasochłonne. Wybór padł na ANT (ant.apache.org),
jednak jeszcze łatwiej go wykorzystać z poziomu edytorów
takich jak Netbeans czy Eclipse.
Jako, że korzystam na codzień z Netbeans,
został on uruchomiony, stworzony najprostszy projekt,
typu Java Application …
dodanych kilka klas w różnych paczkach (z dotnetowego przestrzeni nazw)
Następny krok: trzeba było stworzyć skrypt dla ANTa,
(prawym klawiszem myszy na projekcie -> New -> Other
-> z listy dostępnych szablonów Other -> Ant Build Script
-> nadanie nazwy)
najprościej stworzyć go w głównym katalogu projektu i
nazwać go np.: build_with_janet.xml
Należało dokonać pewnych modyfikacji,
mianowicie dodać polecenie mkdir
oraz javac
<?xml version=”1.0″ encoding=”UTF-8″?>
<project name=”changeme” default=”all” basedir=”.”>
<target name=”all”>
<mkdir dir=”build/dotnet” />
<javac srcdir=”src”
destdir=”build/dotnet”
executable=”G:\zainstalowane\dotnet\janetse-jddk\jdk\bin\javac”
fork=”true”
compiler=”modern”>
<compilerarg value=”-bam:test.dll”/>
</javac>
</target>
</project>
Trochę na temat składni:
mkdir -> twórz katalog (tworzy rekursywnie)
javac -> srcdir – ścieżka do plików źródłowych (domyślnie jest to src w Netbeans)
-> destdir - ścieżka, gdzie zostaną umieszczone pliki classes, czy efekt kompilacji
-> executable - ścieżka do kompilatora javac, który jest spoza standardowego jdk
-> fork=”true” - wskazanie, że używamy zewnętrznego kompilatora
-> compiler=”modern” - wskazanie, że kompilator ma kompilować zgodnie ze standardami kompilatora w wersji co najmniej 1.4
compilerarg -> dodatkowe parametry kompilatora
->value=”-bam:test.dll” – wskazanie, że kompilator jadev ma utworzyć z wszystkich klas
które znajdzie w destdir bibliotekę dll
W przypadku tak prostego projektu przeszło gładko
czyli należało przełączyć się na zakładkę Files
rozwinąć główne drzewo katalogów,
kliknąć prawym klawiszem myszy na nowo utworzony plik,
Run Target->all
i zachciało mi się kompilować projekt typu jetty
(najprostszy serwer j2ee – http://jetty.codehaus.org/jetty/
Problemy, jakie można obecnie napotkać to:
1) samemu trzeba pobrać, wygrzebać implementację jsp (np.: ze źródeł Apache Tomcat)
2) samemu trzeba pobrać mx4j (na standardzie w zwykłej javie dysponujemy tym mechanizmem,
z przestrzeni nazw javax.managment -> http://mx4j.sourceforge.net/
a) i co gorsza, trzeba się było trochę namęczyć, aby wyłączyć BCEL
(też na standardzie używane w Javie) – BCEL to biblioteka służąca
do analizy kodu pośredniego (byte code),
coś ala analizator MSIL służący do generowania szybszych odwołań
do klas, struktur, danych działający poza warstwą Reflection
b) i co gorsza po raz drugi trzeba było usunąć odwołania do loggera z org.apache.commons.logging
c) i tak dalej można było by narzekać, nie wspominając o konieczność usunięcia odwołań
do CORBA
3) gdy już wszystko było przygotowane, kompilowanie się rozpoczęło, trwało, trwało
i naraz kompilator stwierdził
———-
java.lang.reflect.InvocationTargetException: Zgłoszono wyjątek typu ‘java.lang.reflect.InvocationTargetException’.
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.harmony.tools.javac.Compiler.main(Unknown Source)
at org.apache.harmony.tools.javac.Main.compile(Unknown Source)
at org.apache.harmony.tools.javac.Main.compile(Unknown Source)
at org.apache.harmony.tools.javac.Main.main(Unknown Source)
Caused by: System.ArgumentOutOfRangeException: Indeks jest spoza zakresu. Musi mieć wartość nieujemną i mniejszą niż rozmiar kolekcji.
Nazwa parametru: index
w System.Collections.CollectionBase.System.Collections.IList.get_Item(Int32 index)
w Mono.Cecil.Cil.VariableDefinitionCollection.get_Item(Int32 index)
w org.eclipse.jdt.internal.compiler.codegen.CLICodeStream.Stloc(LocalVariableBinding var)
w org.eclipse.jdt.internal.compiler.codegen.CLICodeStream.store(LocalVariableBinding localBinding, Boolean strictfpReq, Boolean valueRequired)
w org.eclipse.jdt.internal.compiler.codegen.CLICodeStream.store(LocalVariableBinding localBinding, Boolean valueRequired)
w org.eclipse.jdt.internal.compiler.ast.LocalDeclaration.generateCode(BlockScope currentScope, CLICodeStream codeStream)
w org.eclipse.jdt.internal.compiler.ast.Block.generateCode(BlockScope currentScope, CLICodeStream codeStream)
w org.eclipse.jdt.internal.compiler.ast.TryStatement.generateCode(BlockScope currentScope, CLICodeStream codeStream)
w org.eclipse.jdt.internal.compiler.ast.Block.generateCode(BlockScope currentScope, CLICodeStream codeStream)
w org.eclipse.jdt.internal.compiler.ast.Initializer.generateCode(BlockScope currentScope, CLICodeStream codeStream)
w org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration.internalGenerateCode(ClassScope classScope, CLIClassFile classFile)
w org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration.generateCode(ClassScope classScope, CLIClassFile classFile)
w org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(CLIClassFile enclosingClassFile)
w org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCILCode(CompilationUnitScope unitScope)
w org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.generateCode()
w org.eclipse.jdt.internal.compiler.Compiler.process(CompilationUnitDeclaration unit, Int32 i)
w org.eclipse.jdt.internal.compiler.Compiler.compile(ICompilationUnit[] sourceUnits)
w org.eclipse.jdt.internal.compiler.batch.Main.performCompilation()
w org.eclipse.jdt.internal.compiler.batch.Main.compile(String[] argv)
w ??CallMethod(Object , Object[] )
w java.lang.reflect.Method.invoke(Object obj, Object[] args)
at Mono.Cecil.Cil.VariableDefinitionCollection.get_Item(Unknown Source)
at org.eclipse.jdt.internal.compiler.codegen.CLICodeStream.Stloc(Unknown Source)
at org.eclipse.jdt.internal.compiler.codegen.CLICodeStream.store(Unknown Source)
at org.eclipse.jdt.internal.compiler.codegen.CLICodeStream.store(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.LocalDeclaration.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.Block.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.TryStatement.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.Block.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.Initializer.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration.internalGenerateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCILCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.generateCode(Unknown Source)
at org.eclipse.jdt.internal.compiler.Compiler.process(Unknown Source)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Unknown Source)
at org.eclipse.jdt.internal.compiler.batch.Main.performCompilation(Unknown Source)
at org.eclipse.jdt.internal.compiler.batch.Main.compile(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
Mi co prawda nie przeszła ochota na testowanie tego narzędzia,
ale jeszcze gwoli ścisłości – dokumentacja dostępnego api
dla tej wersji JRE/JDK
-> http://janetdev.org/janetse/1.5/api/index.html