Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Zjištění dostupného kódu z dané metody

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re: Zjištění dostupného kódu z dané metody

Autor: Maaartin

1:39:06 10.08.2011

> [ital]UC detector jsem teda nezkoušel, ale podle názvu a featurelistu to vypadá na klasiku - objevování unreachable kódu (kód po return, nepoužitá privátní metoda...), to nechci.[/ital]

No to rozhodne ne. To dela eclipse, proc by to delal znova? Navic nic z toho co tam ma mi tak nezni:

Reduce visibility to protected or private:
Select error level for visibility. This option will create markers for code which could be protected, default or private. This is code, which has only references in same package or same class.

Can I trust 100% UCDetector warnings?
No. Check reflection, do a full text search, ask your architect, apply changes carefully.

Why is UCDetector so slow?
When you manually try to find unused code, you search for references, which is slow. UCDetector searches for references all the time and it checks inheritance.

> [ital]No napsal jsem tu toho celkem dost, ale asi teď bude každému jasné, o co mi jde a taky vidíte co funguje a jak. Teď ještě aby to šlo přímo s .java a ne s .class. U některých .class totiž decompiler nezná všechna jména a tak např. parametry metod nemají smysluplné názvy:[/ital]

Jaxem psal, decompilator bych vubec nepouzil: Spust obfuscator, naparsuj jeho vystup, naparsuj zdrojak, vyhod z nej co se nepouzije. Nemelo by to byt prilis slozity, musis rozumet jenom hlavickam metod a umet preskocit vsecko ostatni.

Dalsi moznosti najdes mozna tady: http://stackoverflow.com/questions/162551/how-to-find-unused-dead-code-in-java-projects

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Krokodyyl

22:08:43 09.08.2011

Je fajn, že se to trochu rozjelo. Víc hlav, víc nápadů. Maven jako takový znám, jen jsem jej zatím nepotřeboval a spíš jsem experimentoval s Antem.

Kromě yGuardu jsem zkusil taky ProGuard a samozřejmě jak radil Maaartin, tak s vypnutou obfuskací. Funguje to hezky, ale jen na mnou vytvořeném učebnicovém příkladu. Při pokusu nasadit jej na reálnou knihovnu (cca 150 .jar, přes 40 MB, tisíce tříd) jsem neuspěl. Ten výpis chyb a warningů byl tak dlouhý, že to asi v konečném čase nedám dohromady :-) Chtěl jsem totiž potom zkusit decompiler (bo ProGuard pracuje s bytecodem). Fungovalo, ale fakt jen na ten můj easy example.

Automatizaci tohoto procesu nevyžaduji, chci jen jednorázově dostat minimalistickou verzi kódu, který je nutný pro vykonání mnou po knihovně vyžadované operace - zavolání cca 2-3 metod z cca stejného počtu tříd (dále volaných jich je samozřejmě mnohonásobně víc, ty chcu zjistit).

UC detector jsem teda nezkoušel, ale podle názvu a featurelistu to vypadá na klasiku - objevování unreachable kódu (kód po return, nepoužitá privátní metoda...), to nechci.

Nejdál jsem se tedy dostal s ProGuardem a Java Decompilerem. Ilustrační příklad, na kterém jsem ověřil funkčnost. Jedná se o jeden projekt (ShrinkJar), jehož výstupem je .jar (simuluje knihovnu s mimo jiné mnou hledanou funkčností, ale taky balastem). Druhý projekt (Shrink) reprezentuje můj projekt, který funkčnost knihovny využívá.
(do ProGuardu jdou ale zkompilované verze, tedy .class)

================================================================================
Projekt Shrink:
- 2 zdrojové soubory shrink/MainShrink.java, shrink/Calculator.java

========================================
shrink/MainShrink.java:
[code]
package shrink;

import jarko.Jarculator;

public class MainShrink
{
public static void main(String[] args)
{
/*int array[] = new int[]{1,2,3,4,5};

Calculator c = new Calculator();

System.out.println("Soucet pole = "+c.sumAll(array));*/

Jarculator jTor = new Jarculator();

System.out.println("Dvakrat 8 je: "+jTor.vynasobDvema(8));
}
}
[/code]
========================================
shrink/Calculator.java
[code]
package shrink;

public class Calculator
{
public int unused = 4;

public int add(int a, int b)
{
return a+b;
}

public int sub(int a, int b)
{
return a-b;
}

public int sumAll(int array[])
{
int ret = 0;
for(int i=0; i ret = this.add(ret, array[i]);
}

return ret;
}
}
[/code]
================================================================================
Projekt ShrinkJar:
- 2 zdrojové soubory jarko/Jarculator.java, jarko/TridaKnicemu.java

========================================
jarko/Jarculator.java

[code]
package jarko;

public class Jarculator
{
public int secti(int a, int b)
{
return a+b;
}

public int odecti(int a, int b)
{
return a-b;
}

public int vynasob(int a, int b)
{
return a*b;
}

public int vynasobDvema(int a)
{
return vynasob(a, 2);
}
}
[/code]
========================================
[code]
package jarko;

public class TridaKnicemu
{
public TridaKnicemu()
{
System.out.println("Constructor...");
}

public void doNothing()
{
System.out.println("I m doing nothing");
}
}
[/code]
Tak když tohleto projedu ProGuardem tak, že mu řeknu, aby zachoval metodu main() v shrink.MainShrink, tak výsledkem je jen shrink/MainShrink.class a Jarko.jar s takovýmto obsahem (po decompilaci):

MainShrink.class
========================================
[code]
package shrink;

import jarko.Jarculator;
import java.io.PrintStream;

public class MainShrink
{
public static void main(String[] args)
{
Jarculator jTor = new Jarculator();

System.out.println("Dvakrat 8 je: " + jTor.vynasobDvema(8));
}
}
[/code]

Jarko.jar - jarko/Jarculator.class
========================================
[code]
package jarko;

public class Jarculator
{
public int vynasob(int a, int b)
{
return a * b;
}

public int vynasobDvema(int a)
{
return vynasob(a, 2);
}
}
[/code]

No napsal jsem tu toho celkem dost, ale asi teď bude každému jasné, o co mi jde a taky vidíte co funguje a jak. Teď ještě aby to šlo přímo s .java a ne s .class. U některých .class totiž decompiler nezná všechna jména a tak např. parametry metod nemají smysluplné názvy:
doSomething(int paramInt1, float paramFloat, int paramInt2)
z toho opravdu program těžko pochopím.

No nic, už končím.

K.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Maaartin

13:09:47 09.08.2011

> [ital]@Krokodyyl: Zkusím si pohrát s obfuscatorem yGuard.
To bude asi trochu potíž, výsledkem (záleží na nastavení) bývá změna v návech tříd a metod[/ital]

Jo, to je cilem obfuskace. Ja znam v podstate jenom Proguard (free) a ten to umi vypnout, predpokladam ze i vsecky ostatni.

> [ital]@Maaartin: Tak odhaduju za kdyz sces metody tak na Maven muzes zapomenout.
Určitě ne, Maven (respektive jeho plugin compile) dokáže generovat jar se zdrojovým kódem. Tak jak Krokodyyl položil dotaz, přišlo mi, že potřebuje automatizovanou věc pro opakované překlady.[/ital]

Me slo o to jestli umi vyhodit nejen nepotrebny tridy ale i nepotrebny metody. Umi?

Automatizace s Proguardem taky neni nic narocnyho, jaxem si s tim hral, taxem proste spoustel procesy, nic moc chytryho ale jednoduchy to bylo a jasny tez.

> [ital]@Krokodyyl: Teoreticky bych mohl sledovat importy ve třídách
...[/ital]

Navim pracuji s celyma tridama (krome import static) a on asi potrebuje metody.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Jan33

12:44:44 09.08.2011

Život je někdy docela zábavný. Shodou okolností jsem byl donucen řešit podobný problém. Tak jsem se na to podíval a ....

Původní myšlenka použít Maven Dependency plugin je chybná. Závislosti neřeší na úrovni tříd, ale celých jarů. To jestli je jar v projektu použití získává odněkud z compile pluginu a nevysledoval jsem kde.

K zjištění využitých tříd jsem použil Apache BCEL (http://commons.apache.org/bcel/manual.html). Ten pracuje nad bytecodem a rozloží třídu na jednotlivé instrukce.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Jan33

12:36:54 09.08.2011

@Krokodyyl: Díky za nápady. Škoda, že s mavenem nemám žádné zkušenosti.
Maven zkus, mám v tom i Android projekty a nedokážu si bez něj (zvlášť cizí) projekt představit. Zkus se podívat na http://code.google.com/p/maven-android-plugin/wiki/GettingStarted

@Krokodyyl: Zkusím si pohrát s obfuscatorem yGuard.
To bude asi trochu potíž, výsledkem (záleží na nastavení) bývá změna v návech tříd a metod, tedy pro tebe dost nepoužitelné (i když se generují i převodní tabulky aby se ze stack trace dal zpětně určit kde chyba vznikla, ale i tak mi to přijde jako kanón).

@Maaartin: Tak odhaduju za kdyz sces metody tak na Maven muzes zapomenout.
Určitě ne, Maven (respektive jeho plugin compile) dokáže generovat jar se zdrojovým kódem. Tak jak Krokodyyl položil dotaz, přišlo mi, že potřebuje automatizovanou věc pro opakované překlady.

@Krokodyyl: Teoreticky bych mohl sledovat importy ve třídách
Lexikální analýza je docela problém. Importy pouze určují jmenný prostor, takže v nich je bordel a jestli nepoužíváš nějaký čistič (třeba v Eclipse organizace importů) můžeš tam dostat zcela nepoužité třídy. Nemluvě importu s hvězdičkou a navíc se do importů vkládá i javadoc reference které tě vůbec nezajímají a jen z prostého importu je neodlišíš.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Maaartin

7:49:23 09.08.2011

Takze FindBugs to pry neumi
http://stackoverflow.com/questions/4721142/can-findbugs-detect-unused-public-methods/4752016#4752016
ale slo by to ohnout
http://stackoverflow.com/questions/4721142/can-findbugs-detect-unused-public-methods/4721312#4721312
a pry IntelliJ (free edition) to umi.

Taky jsem nasel
http://www.ucdetector.org/
pro eclipse. To by bylo asi idealni.

Nezapomen poreferovat jestli to k cemu je.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Maaartin

21:47:46 08.08.2011

Tak odhaduju za kdyz sces metody tak na Maven muzes zapomenout. Neco co dela primo s Javou me nenapada, krome UrobSiSam. To by ale nemelo byt tezky:

Spust obfuscator, naparsuj jeho vystup, naparsuj zdrojak, vyhod z nej co se nepouzije. Nemelo by to byt prilis zlozity, musis rozumet jenom hlavickam metod a umet preskocit vsecko ostatni.

Mozna to umi i naky tool jako FindBugs, ci tak nejak a mozna ma plugin do IDE, mrknul bych na to.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Krokodyyl

14:42:22 08.08.2011

Bohužel jak se zdá, tak všechny obfuscatory a code shrinkery pro javu pracují až s bytecodem. Já ale potřebuji vidět přímo osekané zdrojáky. Celá věc se má totiž takto: píšu pro Android a ten nenese všechny rysy "klasické javy". Proto bych chtěl získat z té které knihovny minimalistickou verzi zdrojáků, abych se mohl podívat, jestli je v mých schopnostech je upravit tak, aby šly spustit i na Androidu.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Krokodyyl

13:31:11 08.08.2011

Díky za nápady. Škoda, že s mavenem nemám žádné zkušenosti. Zkusím si pohrát s obfuscatorem yGuard.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Maaartin

5:48:52 08.08.2011

> [ital]Například najdu knihovnu, která obsahuje funkčnost, kterou chci, ale zároveň obsahuje taky mnoho dalšího navíc, co bych ve svém výsledném programu mít nechtěl.[/ital]

Zkontroluj si ale jestli to licence povoluje.

Myslim ze se na to da pouzit obfuskator, ten umi vyhodit vse co neni potreba. Samotnou obfuskaci muzes vypnout. Kdyz pouzivas reflexi tak to nemusi najit vsecko, ale da se mu poradit.

Citovat příspěvek

 

Re: Zjištění dostupného kódu z dané metody

Autor: Jan33

16:29:59 07.08.2011

Osobně bych takový projekt zmavenizoval a rozšířil bych si assembly plugin. Informace o použitých třídách bych čerpal z Dependency pluginu.

* Dependency plugin - http://maven.apache.org/plugins/maven-dependency-plugin/usage.html
* Assembly Plugin - http://maven.apache.org/plugins/maven-assembly-plugin/

Citovat příspěvek

 

Zjištění dostupného kódu z dané metody

Autor: Krokodyyl

13:51:24 07.08.2011

Zdravím,

název tématu na první pohled nemusí být jasný, ale přesně vystihuje to, čeho bych rád dosáhl, ať už nějakým existujícím nástrojem nebo svépomocí. Tak jako existuje tzv. "unreachable code", tedy kód, ke kterému se při provádění programu vůbec nedá dostat, tak já chci pravý opak.

Například najdu knihovnu, která obsahuje funkčnost, kterou chci, ale zároveň obsahuje taky mnoho dalšího navíc, co bych ve svém výsledném programu mít nechtěl.
Nástroj pro takový účel jsem nenašel, tak mě napadlo to zkusit po svém. Předpokladem je, že mám zdrojové kódy té knihovny. Teoreticky bych mohl sledovat importy ve třídách, které použiji a z nich dále sledovat importy, ale to by výsledek zřejmě moc neořezalo. Lepší by bylo sledovat trasu volání metod. Seznam metod se dá snadno zjistit s pomocí reflexe, ale už nevím, jak sledovat další volání metod v těch metodách. Nemůžu jen projít s debuggerem jeden případ volání, protože s jinými parametry se můžou jinak vyhodnotit podmínky a volat zase jiné metody.

Máte nějaké nápady, jak takový úkol vyřešit? Docela by mě to zajímalo a výsledky by byly myslím užitečné.

K.

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: