Applet Java i biblioteki DLL

0

Witam serdecznie.

Piszę właśnie mój pierwszy applet i oczywiście natrafiłem na problem.

Zadaniem appletu jest odczytanie z dysku użytkownika wybranego pliku, sprawdzenie czy jest plikiem video jednego z obsługiwanych typów i wyciągnięcie z niego tzw. Metadata czyli informacji nagłówkowych tj.: długość, rozdzielczość, fps.

Applet korzysta z biblioteki Mediainfo.dll i wrapperów java na nią tj.: MediaInfo.java oraz MediaInfoLibrary.java.

Applet jest self-signed wiec powinien po zatwierdzeniu wyjątków bezpieczeństwa przez użytkownika mieć prawa odczytu jego plików. Z tego co udało mi się wyczytać w internecie applet nie może skorzystać z biblioteki Mediainfo.dll zawartej bezpośrednio z pliku jar lub gdziekolwiek na zdalnym serwerze tylko musi ją umieścić w windows/system32 na maszynie użytkownika. Nie mam tego jeszcze w programie, ale żeby sprawdzić czy to ma sens ręcznie umieściłem bibliotekę w tym folderze, ale applet nadal nie działa. (póki był uruchamiany z eclipse jako java applet lokalnie wszystko działało i program robił co ma robić, tylko po wrzuceniu na serwer pojawiły się problemy).

Pomoże ktoś mi to ogarnąć? Nie mam w javie jeszcze takiego doświadczenia, żeby samemu rozwiązać ten problem.

Z góry dziękuję za ewentualne porady i pomoc. Pozdrawiam i załączam poniżej kod appletu oraz .jar spakowany rarem zawierający wszystkie pliki.
Działanie (lub raczej niedziałanie) appletu można obejrzeć tutaj: http://con3x.com/java/

package video_inspector;

import java.applet.Applet;
import java.io.File;
import java.util.Arrays;
import java.awt.*;
import javax.swing.JOptionPane;
public class video_inspector extends Applet {
	private static final long serialVersionUID = 1L;
	static String[] allowed = {"avi", "mp4", "3gp", "mkv", "ogm", "rmvb", "rm", "mpeg", "mpg", "mpe", "mov", "qt", "wmv"};
	File f;
	public void init() {
        FileDialog fc = new FileDialog(new Frame(), "Wybierz plik wideo");
        fc.setVisible(true);
        fc.setMode(FileDialog.LOAD);
        String selectedFile = fc.getFile();
        String dir = fc.getDirectory();
        if(new File(dir+selectedFile).exists()) {
	        try {
	        	f = new File(dir+selectedFile);
	        	String mimetype = selectedFile.substring(selectedFile.lastIndexOf('.') +1);
        		if(Arrays.asList(allowed).contains(mimetype)) {
		        	MediaInfo info       = new MediaInfo();
		        	info.open(f);
		        	long length = 		f.length();
		        	//String format        = info.get(MediaInfo.StreamKind.Video, 0, "Format", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String duration      = info.get(MediaInfo.StreamKind.Video, 0, "Duration", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String frameRate     = info.get(MediaInfo.StreamKind.Video, 0, "FrameRate", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String width         = info.get(MediaInfo.StreamKind.Video, 0, "Width", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String height        = info.get(MediaInfo.StreamKind.Video, 0, "Height", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	long seconds 		 = Long.parseLong(duration)/1000;
		            String formatx 		 = String.format("%%0%dd", 2);
		            String time			 = String.format(formatx, seconds/3600)+":"+String.format(formatx, (seconds%3600)/60)+":"+String.format(formatx, seconds%60);
		        	//System.out.println("Format: "+format);
		        	System.out.println("Filesize: "+length+" Bytes");
		        	System.out.println("Duration: "+time);
		        	System.out.println("FPS: "+frameRate);
		        	System.out.println("Resolution: "+width+"x"+height);
        		} else {
        			error("Nieprawidłowy format pliku! Tylko pliki wideo!");
        		}
	        } catch(Exception e) {
	        	if(selectedFile!=null) {
	        		error(e.getMessage());
	        	}
	        }
        } else {
        	if(selectedFile!=null) {
	        	error("Plik nie istnieje!");
        	}
        }
	}
	public void paint(Graphics g) {
		g.drawString("Witajcie wszyscy!", 20, 20);
	}
    public void error(String errorr) {
    	JOptionPane pane = new JOptionPane(errorr);
    	pane.setVisible(true);
    	Dialog err = pane.createDialog(this, "Błąd");
        err.setVisible(true);
    	init();
    	destroy();
    	stop();
    }
    public static void main(String args[]) throws java.io.IOException {
    }
}
0

A podpisałeś aplet?

0

Pytanie czy patrzyłeś konsolę javy w przeglądarce?

0

Tak. Ale nie rozumiem o czym ona do mnie rozmawia :)

Java Plug-in 10.3.1.255
Using JRE version 1.7.0_03-b05 Java HotSpot(TM) Client VM
User home directory = C:\Users\Emil Karolak
----------------------------------------------------
Logging set to : true ... completed.
Trace level set to 5: all ... completed.
basic: Added progress listener: sun.plugin.util.ProgressMonitorAdapter@129642c
basic: Plugin2ClassLoader.addURL parent called for http://con3x.com/java/N24video_inspector.jar
network: Cache entry found [url: http://con3x.com/java/N24video_inspector.jar, version: null] prevalidated=true/0
network: Connecting http://con3x.com/java/N24video_inspector.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/N24video_inspector.jar : 304
network: Encoding for http://con3x.com/java/N24video_inspector.jar : null
network: Disconnect connection to http://con3x.com/java/N24video_inspector.jar
cache: Reading Signers from 1066 http://con3x.com/java/N24video_inspector.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\51\16e2aeb3-18534221.idx
cache:  Read manifest for http://con3x.com/java/N24video_inspector.jar: read=649 full=649
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
security: Validate the certificate chain using CertPath API
security: The certificate hasnt been expired, no need to check timestamping info
security: Found jurisdiction list file
security: No need to checking trusted extension for this certificate
security: The CRL support is disabled
security: The OCSP support is disabled
security: This OCSP End Entity validation is disabled
security: Checking if certificate is in Deployment denied certificate store
security: Checking if certificate is in Deployment permanent certificate store
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 2866116 us, pluginInit dt 40597833 us, TotalTime: 43463949 us
network: Cache entry found [url: http://con3x.com/java/jna.jar, version: null] prevalidated=false/0
network: Connecting http://con3x.com/java/jna.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/jna.jar : 304
network: Encoding for http://con3x.com/java/jna.jar : null
network: Disconnect connection to http://con3x.com/java/jna.jar
cache: Reading Signers from 5 http://con3x.com/java/jna.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\14\34cc624e-70f4fbf1.idx
network: No certificate info for unsigned JAR file: http://con3x.com/java/jna.jar
cache:  Read manifest for http://con3x.com/java/jna.jar: read=241 full=241
security: resource name "com/sun/jna/Platform.class" in http://con3x.com/java/jna.jar : java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://con3x.com/java/jna.jar
java.lang.ExceptionInInitializerError
	at n24video_inspector.N24video_inspector.init(N24video_inspector.java:23)
	at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://con3x.com/java/jna.jar
	at com.sun.deploy.security.CPCallbackHandler$ParentCallback.check(Unknown Source)
	at com.sun.deploy.security.CPCallbackHandler$ParentCallback.access$1500(Unknown Source)
	at com.sun.deploy.security.CPCallbackHandler$ChildElement.checkResource(Unknown Source)
	at com.sun.deploy.security.DeployURLClassPath$JarLoader.checkResource(Unknown Source)
	at com.sun.deploy.security.DeployURLClassPath$JarLoader.getResource(Unknown Source)
	at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
	at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at n24video_inspector.MediaInfo.<clinit>(MediaInfo.java:21)
	... 4 more
basic: Removed progress listener: sun.plugin.util.ProgressMonitorAdapter@129642c
security: Reset deny session certificate store
0

O... już wiadomo :) Po pierwsze jar nie jest podpisany tzn. domena z podpisu nijak ma się do domeny z której pobierany jest jar. W wyniku tego Applet jest uruchamiany jako niezaufany i tym samym nie może załadować biblioteki DLL.

0

Aha. Dzięki za info.

A podpowiesz jak to zrobić dobrze?

Ja podpisuję korzystając z tej instrukcji: http://linuxpoison.blogspot.com/2008/06/how-to-create-self-signed-certificates.html

Nie mam pojęcia w jaki sposób podpisać dodając domenę zdalnego serwera :(

0

Dobra. Doczytałem że chodzi o dodatkowe jar z których korzysta applet i je też podpisałem. Teraz jest już właściwy błąd z brakiem dostępu do dll:

basic: Added progress listener: sun.plugin.util.ProgressMonitorAdapter@1b911d2
basic: Plugin2ClassLoader.addURL parent called for http://con3x.com/java/N24video_inspector.jar
network: Cache entry found [url: http://con3x.com/java/N24video_inspector.jar, version: null] prevalidated=true/0
network: Connecting http://con3x.com/java/N24video_inspector.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/N24video_inspector.jar : 304
network: Encoding for http://con3x.com/java/N24video_inspector.jar : null
network: Disconnect connection to http://con3x.com/java/N24video_inspector.jar
cache: Reading Signers from 1066 http://con3x.com/java/N24video_inspector.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\51\16e2aeb3-18534221.idx
cache:  Read manifest for http://con3x.com/java/N24video_inspector.jar: read=649 full=649
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
security: Validate the certificate chain using CertPath API
security: The certificate hasnt been expired, no need to check timestamping info
security: Found jurisdiction list file
security: No need to checking trusted extension for this certificate
security: The CRL support is disabled
security: The OCSP support is disabled
security: This OCSP End Entity validation is disabled
security: Checking if certificate is in Deployment denied certificate store
security: Checking if certificate is in Deployment permanent certificate store
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 2866116 us, pluginInit dt 1110450549 us, TotalTime: 1113316665 us
network: Cache entry found [url: http://con3x.com/java/jna.jar, version: null] prevalidated=true/0
network: Connecting http://con3x.com/java/jna.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/jna.jar : 304
network: Encoding for http://con3x.com/java/jna.jar : null
network: Disconnect connection to http://con3x.com/java/jna.jar
cache: Reading Signers from 1066 http://con3x.com/java/jna.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\14\34cc624e-1a6cc1c8.idx
cache:  Read manifest for http://con3x.com/java/jna.jar: read=299 full=5196
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
java.lang.UnsatisfiedLinkError: Unable to load library 'MediaInfo.dll': Nie mo?na odnale?? okre?lonego modu?
	at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:166)
	at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:239)
	at com.sun.jna.Library$Handler.<init>(Library.java:140)
	at com.sun.jna.Native.loadLibrary(Native.java:393)
	at n24video_inspector.MediaInfoLibrary.<clinit>(MediaInfoLibrary.java:14)
	at n24video_inspector.MediaInfo.<init>(MediaInfo.java:36)
	at n24video_inspector.N24video_inspector.init(N24video_inspector.java:23)
	at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
basic: Removed progress listener: sun.plugin.util.ProgressMonitorAdapter@1b911d2
security: Reset deny session certificate store
0

keytool -genkey -keyalg RSA -keysize 2048 -dname "CN=www.yourdomain.com, O=Default, C=US" -keystore domain.keystore

jeżeli dobrze pamiętam...

0

A ten dll to sam się zainstaluje w momencie pierwszego wywołania biblioteki czy trzeba samodzielnie System.load wołać?

0

Będzie się instalował, ale póki co go ręcznie wrzuciłem do system32 i nie działa ;)

0

YEAH! Podpisałem jak mówiłeś i dodatkowo dll wrzuciłem do program files/java/jre7/bin i DZIAŁA!

Dzięki :)

Teraz jeszcze muszę napisać kopiowanie dll z jara to tego folderu i finito :)

0

Po co tak kombinować. Nie możesz tego appletu przez webstart wrzucić? Tam jest opcja do dostarczania natywnych libów, raczej powinna działać.

http://lopica.sourceforge.net/faq.html#native

0

Moge potwierdzic ze dziala ;d

0

Już nie chciałbym bawić się w takie rozwiązania bo w tamtym się w ogóle nie orientuję.

Teraz juz problemem pozostało tylko poprawne skopiowanie biblioteki z serwera na dysk użytkownika.

Robię to tak:

W applecie przekazuję parametr file:

<applet code="n24video_inspector.N24video_inspector.class" codebase="http://con3x.com/java/" archive="N24video_inspector.jar" name="N24 Video Inspector" mayscript="MAYSCRIPT" scriptable="SCRIPTABLE" width="500" height="500"><param name="file" value="MediaInfo.dll" /></applet>

i wykorzystuję to w klasie tak:

		String javaHome=System.getProperty("java.home");
		try {
			String file=getParameter("file");
			File inputFile = new File(javaHome+"\\lib\\ext");
			URL copyurl;
			InputStream outputFile;
			copyurl=new URL(getCodeBase(), file);
			outputFile=copyurl.openStream();
			FileOutputStream out=new FileOutputStream(inputFile);
			int c;
			while((c=outputFile.read())!=-1) {
				out.write(c);
			}
			outputFile.close();
			out.close();
		} catch(Exception e) {
			System.out.println("Nie udało się załadować biblioteki MediaInfo.dll");
		}

Wynik na konsoli:

basic: Starting applet teardown
basic: Finished applet teardown
basic: Removed progress listener: sun.plugin.util.ProgressMonitorAdapter@b41cfa
plugin2manager.parentwindowDispose
basic: Added progress listener: sun.plugin.util.ProgressMonitorAdapter@6aacbf
basic: Plugin2ClassLoader.addURL parent called for http://con3x.com/java/N24video_inspector.jar
security: Validate the certificate chain using CertPath API
security: The certificate hasnt been expired, no need to check timestamping info
security: Found jurisdiction list file
security: No need to checking trusted extension for this certificate
security: The CRL support is disabled
security: The OCSP support is disabled
security: This OCSP End Entity validation is disabled
security: Checking if certificate is in Deployment denied certificate store
security: Checking if certificate is in Deployment permanent certificate store
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 1315439 us, pluginInit dt 16516693 us, TotalTime: 17832132 us
network: Cache entry not found [url: http://con3x.com/java/MediaInfo.dll, version: null]
network: Connecting http://con3x.com/java/MediaInfo.dll with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
Nie udało się załadować biblioteki MediaInfo.dll

Czyli tak jakby się łączy z serwerem a potem wywala od razu błąd. (a plik na serwerze istnieje). Jakieś porady? Proszę uprzejmie o pomoc.

0

Uściśliłem błąd:

Nie udało się załadować biblioteki MediaInfo.dll 
java.io.FileNotFoundException: C:\Program Files (x86)\Java\jre7\lib\ext (Odmowa dostępu)
	at java.io.FileOutputStream.open(Native Method)
	at java.io.FileOutputStream.<init>(Unknown Source)
	at java.io.FileOutputStream.<init>(Unknown Source)
	at n24video_inspector.N24video_inspector.init(N24video_inspector.java:24)
	at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Dlaczego jest odmowa dostępu? :(

0

a czy katalog na pewno istnieje? IMO znacznie lepszą metodą jest "instalacja" w system32 choć antywirus będzie miał uprzedzenia co do tej metody.

0

Nie wiem jak to jest na windowsach, ale system plikow tez ma jakies uprawnienia. Tzn. jesli ty uruchamiasz applet (firefoxa) jako Koziolek, i aplet jest podpisany i mozesz pisac w swoich katalogach, niekoniecznie oznacza to ze mozesz pisac w c:/program files. Z tego co pamietam to vista i 7 wlasnie maja takie zabezpieczenia. Tak samo u mnie: nie zapiszesz nic w /usr/lib/jvm/java7/ext bo tam pisac moze tylko root. Podpisanie apletu tu nie pomoze bo jest uruchamiany z innym uid i guid.
Wierz mi, deploy appletu z jnlp jest o wiele lepszym trwalszym i poprawnym rozwiazaniem. Ja jako user bym w zyciu nie pozwolil wrzucac mi jakichs dll do katalogu javy, przeciez to jest luka jak skurwysyn...

0

Poradizłem sobie z tymi problemami.

Został już naprawdę ostatni: jak pobrać ścieżkę do java.home dla różnych jre. Mam zainstalowane jre6 i jre7, aplikacja odpala się w jre7 ale System.getProperty("java.home"); wskazuje na folder programfiles/java/jre6 i tam też zapisuje mi plik dll a jre7 go tam nie może znaleźć. Mogę jakoś decydować w któym jre zapiszę plik? (chodzi o to, że by w tym które jest używane do uruchomienia aplikacji to się zapisało albo najlepiej w KAŻDYM jre i po sprawie).

Kod:

		try {
			String file=getParameter("file");
			File inputFile=new File(javaHome+"\\lib\\ext\\MediaInfo.dll");
			boolean success=inputFile.createNewFile();
		    if(success) {
				URL copyurl;
				InputStream outputFile;
				copyurl=new URL(getCodeBase(), file);
				outputFile=copyurl.openStream();
				FileOutputStream out=new FileOutputStream(inputFile);
				int c;
				while((c=outputFile.read())!=-1) {
					out.write(c);
				}
				outputFile.close();
				out.close();
		    }
		} catch(Exception e) {
			System.out.println("Nie udało się załadować biblioteki MediaInfo.dll ");
			e.printStackTrace();
		}
0

mućka, tylko pamiętaj, że "odmowa dostępu" może oznaczać np. brak określonego katalogu. To jest taki feature javy dzięki któremu można się naciąć na szukanie błędu w innym miejscu.

0

Witam ponownie.

Tamte problemy już rozwiązane ale pojawił się kolejny. A raczej kolejne pytanie.

Czy i jak da się z apletu Java w wybranym momencie np. po policzeniu kilku rzeczy zmodyfikować wartość wybranego pola input w formularzu HTML na stronie z apletem? (może być przy użyciu JS)

Da się?

Pzdr.

0

Dzięki wielkie!
Bardzo mi to pomogło :)

Dziękuję wszystkim za pomoc. Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1