Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za duben (YouTube).
Provozovatel čínské sociální sítě TikTok dostal v Evropské unii pokutu 530 milionů eur (13,2 miliardy Kč) za nedostatky při ochraně osobních údajů. Ve svém oznámení to dnes uvedla irská Komise pro ochranu údajů (DPC), která jedná jménem EU. Zároveň TikToku nařídila, že pokud správu dat neuvede do šesti měsíců do souladu s požadavky, musí přestat posílat data o unijních uživatelích do Číny. TikTok uvedl, že se proti rozhodnutí odvolá.
Společnost JetBrains uvolnila Mellum, tj. svůj velký jazykový model (LLM) pro vývojáře, jako open source. Mellum podporuje programovací jazyky Java, Kotlin, Python, Go, PHP, C, C++, C#, JavaScript, TypeScript, CSS, HTML, Rust a Ruby.
Vývojáři Kali Linuxu upozorňují na nový klíč pro podepisování balíčků. K původnímu klíči ztratili přístup.
V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.
Oficiální ceny Raspberry Pi Compute Modulů 4 klesly o 5 dolarů (4 GB varianty), respektive o 10 dolarů (8 GB varianty).
Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.
Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.
Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.
Představte si, že píšete rozsáhlou aplikaci, informační systém například. Prvním krokem je sesbírání všech nutných zdrojů a knihoven a správné překompilování všech modulů programu, dalším správné vytvoření binárních souborů a posledním například nasazení. Představte si, že programujete v rámci velkého vývojového týmu. Výroba software může představovat mnoho kroků navíc, od kontroly dodržování stylu psaní kódu přes revizi kódu až po automatické testování či nasazení vyvíjené komponenty na aplikační server. Asi je jasné, že tohoto cíle půjde jen těžko dosáhnout pomocí několika skriptů příkazového interpretru či souborů s příponou BAT. Bylo by to zbytečné a pracné, když máme všichni k dispozici tak silný nástroj, jakým je Jakarta Ant.
Stáhnete-li z Internetu zdrojové kódy nějakého open source programu
psaného v Javě, marně budete hledat soubor Makefile
. V drtivé
většině případů tam totiž najdete build.xml
. To je rukopis
Antu, programu, jenž je vyvíjen pod záštitou projektu Jakarta v Apache
Software Foundation, kde mimo jiné najdete spoustu programů, které se byť
jen okrajově týkají jazyku Java a serverů. Než začneme s popisem Antu,
doporučuji si ho stáhnout, pokud jste tak již neučinili dříve. K běhu Antu
potřebujete pouze JRE Java 2.
Instalace Antu je stejně jednoduchá, jako je instalace jakéhokoli jiného
programu psaného v Javě. Nejdříve zkontrolujte, že máte nainstalovánu Javu
(příkazem java -version
), Ant není náročný a postačí mu verze
1.2, doporučuji však verzi 1.4. Dalším krokem je rozbalení (kam chcete) a
úplně posledním krokem je nastavení dvou proměnných prostředí:
ANT_HOME
a PATH
. První proměnnou nastavte na
cestu, kde jste rozbalili Ant a druhou na hodnotu
$ANT_HOME/bin
. Nyní by měl zafungovat příkaz ant
-version
- Jakarta Ant se slušně představí a ukončí se.
Ant (z angl. slova mravenec) dokáže zastat hned několik rolí vývojového týmu, především programátora nebo testera. Zvládne bez jediného slova tu špinavou, mravenčí práci. Zkratka Ant (Another Neat Tool) mu prostě sedí. Jako programátor si bez Antu již nedovedu představit život, dělá za mě vše (tedy kromě programování). Od stažení zdrojových kódů z CVS, jejich úklidu a sestavení (které není v některých projektech plných závislostí až tak triviální), přes vytvoření EJB popisovacích souborů, verifikaci pomocí specializovaných nástrojů, vytvoření balíčků JAR, zbavení binárek přebytečných instrukcí, jejich indexaci a digitálnímu podepsání až po nahrání na FTP server či spuštění automatizovaných testů pomocí frameworku JUnit. Připoutejte se, prosím, příští stanice planeta Jakarta.
Řekněme, že máme program HelloWorld a chceme jej pomocí Antu přeložit.
Program je reprezentován jednou třídou
(cz.zapletal.HelloWorld
), kterou budeme chtít samozřejmě
přeložit standardním kompilátorem Javy a zabalit do archivu JAR přesně dle
specifikace (tj. včetně souboru MANIFEST
).
Nejdříve bych se pozastavil nad adresářovou strukturou. Pro zdrojové
kódy bývá dobrým zvykem vytvořit samostatný adresář (obvykle nazvaný
src
) a pro výsledné binární soubory (soubory
CLASS
) pak taktéž speciální adresář (bin
nebo
build
- podle vaší chuti). Máme nyní "místo" v adresáři
projektu pro jiné soubory - pro sestavovací soubor Antu. Má obvyklý název
build.xml
, pokud zvolíme jiný, musíme jej explicitně při
každém volání Antu specifikovat. Otevřeme si soubor
priklad1/build.xml
:
<?xml version="1.0" encoding="UTF-8" ?> <project default="dist"> <property name="name" value="priklad1"/> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <mkdir dir="${build}"/> <mkdir dir="${dist}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <jar jarfile="${dist}/${name}.jar" basedir="${build}"/> </target> <target name="clean"> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>
Co vás asi nepřekvapí, je struktura souboru, je to obyčejný XML. Má to několik výhod, mezi ty nejzřetelnější řadím jednoduchost XML (programátoři tento jazyk zvládnou rychle) nebo podpora kontroly podle DTD definice, kterou v distribuci Antu najdete taktéž (dělají to všechny moderní IDE prostředí, navíc umějí pohodlně doplňovat pomocí CTRL+Enter). Na začátku máme deklarováno kódování, což je opět výhoda - nemusíte se bát používat češtinu.
Hlavním elementem XML souboru Antu je project
, jehož jméno
je povinné a neměnné (viz DTD), jeho jediným povinným parametrem je
default
. Ten určuje implicitní cíl. Sestavovací skript podobně
jako soubor Makefile
definuje několik cílů (akcí). Takovou
akcí může být například vyčištění prostoru (adresářů), kompilace nebo
balení souboru JAR. A skutečně, tak je tomu i v našem příkladu. Pomineme-li
elementy property
, najdeme v elementu project
několik elementů s názvem target
. Konkrétně jsou to
init
, compile
, dist
a
clean
.
Cíl init
má na starosti vytvoření inicializačních úkonů,
které je nutno udělat před každou činností. Konkrétně to je vytvoření
adresářové struktury (element mkdir
). Všimněte si, že systém
Ant dovoluje vytváření proměnných pomocí elementu property
,
odkaz na proměnnou se provádí pomocí standardních znaků dolaru a složených
závorek. Asi nejdůležitějším cílem je compile
, jež provede
kompilaci zdrojových kódů z adresáře src
(proměnná
${src}
) do adresáře dist
.
Skvělou věcí v Antu jsou závislosti cílů, jeden cíl totiž může záviset
na jiném. V příkladě je cíl compile
přímo závislý na tom, aby
byl vytvořen adresář build
, jinak by kompilace samosebou
selhala. Proto jsem v elementu target
uvedl parametr
depends
s hodnotou init
. Nyní již máme všechny
dostupné informace pro to, abychom spustili kompilaci. Provedeme to
zavoláním cíle compile
takto:
# ant compile
Sestavovací systém Ant od Apache Software Foundation nyní načte
konfigurační soubor, ověří jeho syntaxi a pokusí se provést činnost, jež
najde v souboru pod názvem compile
. Zjistí, že je závislá na
činnosti s názvem init
, provede ji tedy (vytvoří příslušné
adresáře) a poté již zkompiluje všechny soubory v adresáři src
a výsledek ukládaje do adresáře build
. Jak prosté.
Pozorný čtenář si jistě všiml dalších dvou cílů: dist
a
clean
. První jmenovaný zabalí všechny soubory z adresáře
build
do souboru dist/project1.jar
a druhý
provede úklid (smazání) všech adresářů podobně, jako to dělá
make clean
. Pokud nyní spustíme příkaz ant
bez parametrů, provede se implicitní cíl, tj. dist
, ten je
závislý na compile
a compile
na
initu
. Jednotlivé akce se tedy provedou takto:
init
, compile
, dist
. Jsme hotovi,
můžeme provést příkaz ant clean
a přejít do adresáře s
dalším příkladem.
V požadavcích uvedených výše jsme chtěli vytvořit soubor
MANIFEST
. Ten sice Ant automaticky vytvořil, ale žádné
hodnotné informace do něj nevložil. Rádi bychom tam samozřejmě měli cestu k
hlavní třídě, aby se program dal spustit pouhým příkazem
java -jar
příkazem nebo poklepáním myši. A přidejme si
ještě několik dalších požadavků: budeme chtít automaticky při každém
sestavení inkrementovat číslo verze programu a uvést toto číslo přímo v
programu, budeme chtít provést automatické testy pomocí JUnitu a ještě
bychom například mohli provést "kompresi" souborů JAR pomocí yGuard
obfuscatoru (toto slovo se velmi špatně překládá a mělo by to být asi:
znehodnocení výsledného bytekódu Javy pro zpětné reverzní inženýrství,
vedlejším efektem této činnosti je zmenšení souborů CLASS).
Než se pustíme do prvního úkolu, bude lepší všechny proměnné
(properties) ze souboru build.xml
přesunout do zvláštního
souboru default.properties
. Je to zcela běžná praxe a
poskytuje řadu výhod. Ant lze nastavit tak, aby při hledání proměnných
souborů nejdříve prohledal domovský adresář a pak teprve adresář projektu.
Toho se dá s výhodou využít například ke globálnímu nadefinování různých
knihoven, jména vývojáře, hesla do CVS či FTP a podobně. Upravíme tedy
build.xml
tak, že odstraníme elementy property
a
doplníme zápis do souboru MANIFEST
.
<property file="${user.home}/build.properties" /> <property file="build.properties" /> <property file="build.number"/> <target name="dist" depends="compile"> <jar jarfile="${main.jar}" basedir="${build}" index="true" includes="**/*.class,**/*.properties,**/*.png,**/*.jpeg" excludes="**/*Test.class"> <manifest> <attribute name="Built-By" value="${user.name}" /> <attribute name="Main-Class" value="${jar.mainclass}" /> <attribute name="Class-Path" value="${jar.classpath}" /> </manifest> </jar> <copy todir="${dist}"> <fileset dir="${lib}"> <include name="**/*.jar"/> </fileset> </copy> </target>
Na začátku celého skriptu načteme proměnné ze souboru, ten je v tomto formátu:
# proměnné name = priklad2 Name = Priklad2 version = 1.0 src = src build = build docs = docs lib = lib dist = dist junit = junit temp = temp
Elementem manifest
vytvoříme kýžený soubor
MANIFEST
a Java archiv půjde spustit pouhým poklepáním (díky
vlastnosti Main-Class
). Proměnné jar.mainclass
a
jar.classpath
jsou nadefinovány v properties
souboru, proměnná user.name
je standardní proměnnou prostředí
Java, které můžeme v Antu využít. Soubor MANIFEST
ale nebude
plně vyhovovat specifikaci. Pro názornost jsem vypustil některé další
povinné vlastnosti, jakými jsou název programu či dodavatel. Všimněte si
parametrů, které jsem přidal.
Indexování v některých případech může urychlit načítání souborů JAR
(proto jsem jej nastavil na true
), pomocí atributů
includes/excludes
jsem archivátoru sdělil, že chci
překlad/kopírování aplikovat pouze na soubory určitého typu, a že chci
vyloučit všechny soubory *Test.class
(kde se nacházejí
automatické testy JUnit, které je zbytečné s aplikací distribuovat). Je
totiž velmi dobrým zvykem ihned po napsání třídy (např. Trida
)
vytvořit i testovací třídu (TridaTest
) a umístit ji do
stejného balíčku. Jak později ukážu, zpracujeme ji automaticky pomocí
JUnitu.
Smeťme ze stolu druhý požadavek: zvyšování verze. Ant je toho schopen
pomocí jednoho příkazu (resp. elementu, ale už tak je v článku poněkud
"přeelementováno", a proto budu používat pro elementy XML souboru používat
výraz příkaz
) vytvořit soubor
build.number
, do kterého vloží jedinou proměnnou s číslem
sestavení. Tím příkazem je buildnumber
a stačí jej vložit do
nějakého cíle, který se pokaždé volá, například init
. Takto by
to mohl vypadat vygenerovaný soubor:
#Build Number for ANT. Do not edit! #Wed Feb 11 13:56:35 CET 2004 build.number=16
Stačí pak použít soubor načíst na začátku skriptu build.xml
a proměnnou build.number
použít tam, kde je to třeba.
Například v názvu souboru JAR, nebo právě ve filtrech. Chceme-li totiž před
každou kompilací vložit do zdrojových kódů informaci o čísle sestavení,
můžou nám posloužit právě filtry. Jeden z příkazů (konkrétně
copy
) má jako atribut hodnotu filter
, pokud je
nastavena na pravdu (true
, yes
, on
nebo 1
), Ant při kopírování bude zaměňovat určité vzory. Toho
můžeme využít. Do zdrojového kódu zaneseme vzor @VERSION@
např. takto:
public static final String VERSION = "@VERSION@"; <target name="pre-compile" depends="init"> <!-- soubory java filtrujeme --> <copy todir="${temp}" filtering="true"> <fileset dir="${src}"> <include name="**/*.java"/> </fileset> <filterset> <filter token="VERSION" value="${version}.${build.number}"/> </filterset> </copy> <!-- ostatni jen kopirujeme --> <copy todir="${temp}" filtering="false"> <fileset dir="${src}"> <include name="**/*.*"/> <exclude name="**/*.java"/> </fileset> </copy> </target> <target name="compile" depends="pre-compile"> <javac srcdir="${temp}" encoding="${encoding}" debug="${debug}" optimize="on" classpathref="classpath" destdir="${build}"/> </target>
Soubor před kompilací nakopírujeme do dočasného adresáře s použitím
filtru, který zamění vzor na číslo verze a číslo sestavení (např. 1.0.198).
Toho docílíme změnou cíle compile
, jak je vidět na výpisu
číslo 3. Přidal jsem cíl pre-compile
, jenž překopíruje všechny
soubory z adresáře src
do temp
, přičemž provede
filtrování (záměnu vzoru @VERSION@
za skutečnou verzi a číslo
sestavení), teprve pak se provede cíl compile
, který je
závislý na pre-compile
.
Pravda, řešení přes adresář temp
je trošku těžkopádné,
nicméně u větších projektů se kopírování zdrojových kódů před kompilací
nevyhnete (například je nutno minimálně použít native2ascii
u
souboru s vlastnostmi a podobně). Ale nemusíte mít z toho strach, Ant
automaticky pozná, který soubor byl změněn, nekopíruje tedy u každého
sestavení všechno. Jak jste si všimli, přidal jsem několik parametrů i
příkazu javac
, aby šly ovlivňovat pomocí proměnných, a
aktivoval jsem optimalizaci překladače.
Příklad s automatickým testováním pomocí JUnit jsem vybral záměrně.
Předem bych chtěl apelovat, že jsem zastáncem pravidla "Kdo nepoužívá JUnit
jako by nebyl" a je pro mě zcela zásadní kniha Test driven
development od Kenta Becka (mimochodem skvělý autor, jeho bestseller
Effective Java je jednou z nejlepších knih o Javě vůbec - obě knihy
vyšly u Grady i v češtině). A navíc si ukážeme, jak se v Antu zachází s
proměnnou CLASSPATH
. Změníme tedy náš motivační příklad tak,
aby byl schopen spouštět automatické testy pomocí JUnitu.
Co k tomu budeme potřebovat? Příkaz junit
, který umí
spouštět testy, je tzv. volitelný task
. Znamená to, že k běhu
tohoto příkazu je nutná nějaká dodatečná knihovna. Knihovnu Ant sám
neobsahuje a je potřeba si ji stáhnout. Pro línější jedince jsem vytvořil
cíl grab-junit
, který se automaticky aktivuje, jestliže není
knihovna nalezena, kdykoli je Ant spuštěn.
<available file="${ant.home}/lib/junit.jar" property="junit.present"/> <target name="grab-junit" unless="junit.present"> <echo>JUnit not present, downloading...</echo> <mkdir dir="${temp}"/> <mkdir dir="${lib}"/> <get src="${junit.url}" dest="${temp}/temp.zip"/> <echo>Unzipping, cleaning...</echo> <unzip src="${temp}/temp.zip" dest="${temp}"/> <copy todir="${ant.home}/lib" flatten="yes"> <fileset dir="${temp}"> <include name="**/junit.jar"/> </fileset> </copy> <delete dir="${temp}"/> <echo>Done.</echo> <fail message="Please run again the Ant"/> </target>
Proměnná junit.present
bude nastavena, pokud existuje
soubor ANT_HOME/lib/junit.jar
. Cíl grab-unit
se
spustí jen tehdy, není-li tato proměnná nastavena, díky parametru
unless
. Jednoduchost sama. Takže předpokládám, že máme
knihovnu na svém místě, nyní na začátek skriptu vložíme nastavení cesty
CLASSPATH
. Nejen že můžeme dynamicky tuto proměnnou (resp. je
to cesta - path
) měnit, ale ono i vkládání souborů či celých
adresářů je naprosto triviální. Například chceme-li vždy přidat do
CLASSPATH
všechny soubory typu JAR z adresáře lib, pak stačí
použít element classpath
v tomto tvaru:
<classpath> <fileset dir="${lib}"> <include name="*.jar" /> </fileset> </classpath>
Je nutno si uvědomit, kdy se vnořený element classpath
používá. Jednou z možností je při kompilaci - když náš program využívá
nějakou knihovnu, musíme překladači sdělit, kde ji najde. Tady element
classpath
použijeme uvnitř příkazu javac
:
<javac srcdir="${temp}" destdir="${build}"> <classpath> <fileset dir="${lib}"> <include name="*.jar" /> </fileset> </classpath> </javac>
Další z možností je, když nějaký program pomocí Antu spouštíte (ano, i
to lze, pomocí elementu java
). Přirozeně totiž musíte
classpath
nastavit. Je ale zbytečné vnořovat tento element
znovu a znovu všude tam, kde je to třeba. Ve svých projektech to dělám
jednoduše, vytvořím si proměnnou typu cesta (<path>
) a
pojmenuji ji classpath
. Na tu se pak při kompilaci a jiných
činnostech jen odkazuji. Je to vidět na příkladu 2, který je na CD.
Pamatujete ještě na ty BAŤáky, které volali jiné BAŤáky v dobách Javy 1.1.8
a Windows 98? Já ano a bylo to někdy velmi frustrující, s tím je teď
konec.
Nyní se konečně dostáváme k testování pomocí JUnitu. Vytvořme na začátku
skriptu proměnnou classpath
tak, aby nejenže obsahovala
všechny knihovny potřebné pro program, ale také adresář build
.
Poté můžeme v cíli test
aktivovat volitelný task JUnit a
použít jej (s vnořeným elementem classpath
s odkazem:
<classpath refid="classpath"/>
). Příkaz
junit
má mnoho parametrů, jejich přesný význam najdete v
dokumentaci Antu. Následující cíl spustí všechny testy, které v celém
stromu zdrojových kódů najde. Mají název *Test.java
, jak jsem
doporučoval, pamatujete?
<mkdir dir="${lib}"/> <path id="classpath"> <pathelement location="${build}"/> <pathelement path="${classpath}"/> <fileset dir="${lib}"> <include name="*.jar"/> </fileset> </path> <target name="test" depends="grab-libs,compile"> <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"/> <mkdir dir="${junit}"/> <junit printsummary="yes" haltonfailure="no" tempdir="${junit}"> <classpath refid="classpath"/> <formatter type="plain"/> <batchtest todir="${junit}"> <fileset dir="${src}"> <include name="**/*Test.java"/> </fileset> </batchtest> </junit> </target>
Vidíme, že cíl test
je závislý na kompilaci, no ovšem,
JUnit přece spouští zkompilované třídy. Na začátku cíle zavedeme task
pomocí příkazu taskdef
, poté vytvoříme adresář, kde se budou
shromažďovat výsledky, a nakonec spustíme vlastní proces testování.
Všimněte si typu výstupu (plain), junit task
totiž umí
výsledky dodat ve formátu XML. Není pak problémem vytvořit si XSL styl a
transformovat výsledek do přehledné HTML stránky (samozřejmě pomocí
vestavěného tasku).
Posledním požadavkem bylo znehodnocení bytekódu (obfuskace). Oblíbil
jsem si open source program yGuard, který sice nedosahuje kvalit komerčního
Zelix KlassMasteru, ale obsahuje Ant task - přesně to potřebujeme. Navíc -
open source programy se nemusí bránit reverznímu inženýrství, jde spíše jen
o zmenšení souborů JAR a tohle umí yGuard na jedničku. Vše si můžete
prohlédnout v dalším
příkladu. Opět se knihovna sama stáhne z Internetu, nainstaluje a při
dalším spuštění příkazu ant obfuscate
se již provede
zeštíhlení výsledného kódu.
Poslední věcí, na kterou bych rád upozornil, je výborný task
Checkstyle
. Pomocí této knihovny (3MB) je možno přes Ant volat
hloubkovou kontrolu zdrojového kódu neboli audit. Najdete ji na CD, ale
pokud ji nerozbalíte do ANT_HOME/lib
, sestavovací skript z
příkladu 2 knihovnu stáhne a nainstaluje, stačí poté použít příkaz
ant check
. V adresáři check
se vytvoří podrobný
report auditu (v HTML) na zásady psaní kódu podle specifikace od firmy Sun.
Checkstyle také kontroluje některé často vyskytující se chyby při psaní
kódu, doporučuji prostudovat manuál a modifikovat
checkstyle.xml
podle svých představ (implicitně je velmi
přísný).
Bohudík není. Ant toho umí mnohem více a kdybyste snad nějakou vlastnost v následujícím (nyní již telegrafickém) přehledu nenašli, poohlédněte se po tasku třetí strany, nebo si takovou činnost do Antu doprogramujte. Ant umí:
Ant je ve své podstatě zavedený produkt, dnes se již nepotkáte s prostředím IDE, které by nemělo alespoň základní podporu kompilace a sestavování pomocí Antu. Pokud máte oblíbenou příkazovou řádku, nic vám nebrání ji nevyužít. Jste-li zastánci myši, můžete použít IDE nebo si stáhnout jednoduchý okenní editor na Ant XML soubory jménem Antidote (je na stránkách projektu Ant).
Nástroje: Tisk bez diskuse
Tiskni
Sdílej:
set ANT_HOME=c:\ant set JAVA_HOME=c:\jdk-1.5.0.05 set PATH=%PATH%;%ANT_HOME%\binproste nevim jak ant rozchodit muzete mi nekdo poradit,please?