Skip to content

Commit f47cfc1

Browse files
author
jossonsmith
committed
Improve ClazzLoader so that ClazzLoader will take another loading try in bad network environment.
1 parent d6884fb commit f47cfc1

1 file changed

Lines changed: 95 additions & 9 deletions

File tree

sources/net.sf.j2s.java.core/src/java/lang/ClassLoader.js

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ ClazzLoader.jarClasspath = function (jar, clazzes) {
365365

366366
/* public */
367367
ClazzLoader.registerPackages = function (prefix, pkgs) {
368+
ClazzLoader.isInnerLoaded = true;
368369
var base = ClazzLoader.getClasspathFor (prefix + ".*", true);
369370
for (var i = 0; i < pkgs.length; i++) {
370371
if (window["Clazz"] != null) {
@@ -542,7 +543,16 @@ ClazzLoader.mapPath2ClassNode = new Object ();
542543
ClazzLoader.xhrOnload = function (transport, file) {
543544
if (transport.status >= 400 || transport.responseText == null
544545
|| transport.responseText.length == 0) { // error
545-
// TODO: Maybe should take another try before ignoring
546+
var fs = ClazzLoader.failedScripts;
547+
if (fs[file] == null) {
548+
// Silently take another try for bad network
549+
fs[file] = 1;
550+
ClazzLoader.loadedScripts[file] = false;
551+
ClazzLoader.loadScript (file);
552+
return;
553+
} else {
554+
alert ("[Java2Script] Error in loading " + file + "!");
555+
}
546556
ClazzLoader.tryToLoadNext (file);
547557
} else {
548558
try {
@@ -577,6 +587,14 @@ ClazzLoader.emptyOnRSC = function () {
577587
/* private */
578588
ClazzLoader.lastScriptPath = null;
579589

590+
/* protected */
591+
/*-# failedScripts -> fss #-*/
592+
ClazzLoader.failedScripts = new Object ();
593+
594+
/* protected */
595+
/*-# failedHandles -> fhs #-*/
596+
ClazzLoader.failedHandles = new Object ();
597+
580598
/**
581599
* Load *.js by adding script elements into head. Hook the onload event to
582600
* load the next class in dependency tree.
@@ -646,14 +664,15 @@ ClazzLoader.loadScript = function (file) {
646664
transport.send (null);
647665
} catch (e) {
648666
alert ("[Java2Script] Loading file error: " + e.message);
649-
throw e;
667+
ClazzLoader.xhrOnload (transport, file);
668+
//throw e;
650669
}
651670
} else {
652671
try {
653672
transport.send (null);
654673
} catch (e) {
655674
alert ("[Java2Script] Loading file error: " + e.message);
656-
throw e;
675+
//throw e;
657676
}
658677
ClazzLoader.xhrOnload (transport, file);
659678
}
@@ -663,14 +682,18 @@ ClazzLoader.loadScript = function (file) {
663682
var script = document.createElement ("SCRIPT");
664683
script.type = "text/javascript";
665684
script.src = file;
685+
var head = document.getElementsByTagName ("HEAD")[0];
666686

667687
if (ignoreOnload) {
668-
document.getElementsByTagName ("HEAD")[0].appendChild (script);
688+
head.appendChild (script);
669689
// ignore onload event and no call of ClazzLoader.scriptLoading
670690
return ;
671691
}
672692
// Alert when the script is loaded
673693
if (typeof (script.onreadystatechange) == "undefined") { // W3C
694+
/*
695+
* What about Safari?
696+
*/
674697
/*
675698
* Opera will trigger onload event even there are no related *.js
676699
*/
@@ -693,6 +716,16 @@ ClazzLoader.loadScript = function (file) {
693716
script.onerror = function () { // Firefox/Mozilla
694717
this.onerror = null;
695718
var path = arguments.callee.path;
719+
var fss = ClazzLoader.failedScripts;
720+
if (fss[path] == null) {
721+
// silently take another try for bad network
722+
fss[path] = 1;
723+
ClazzLoader.loadedScripts[path] = false;
724+
ClazzLoader.loadScript (path);
725+
return;
726+
} else {
727+
alert ("[Java2Script] Error in loading " + path + "!");
728+
}
696729
ClazzLoader.scriptLoaded (path);
697730
if (ClazzLoader.loadingTimeLag >= 0) {
698731
window.setTimeout (function () {
@@ -704,19 +737,60 @@ ClazzLoader.loadScript = function (file) {
704737
};
705738
script.onerror.path = file;
706739
} else { // IE
740+
script.defer = true;
707741
script.onreadystatechange = function () {
708-
if (this.readyState != "loaded" && this.readyState != "complete") {
742+
var ee = arguments.callee;
743+
var path = ee.path;
744+
var fhs = ClazzLoader.failedHandles;
745+
var fss = ClazzLoader.failedScripts;
746+
var state = "" + this.readyState;
747+
// alert (state + "/" + this.src);
748+
if (state != "loaded" && state != "complete") {
709749
/*
710-
* When no such *.js existed for local file system, IE will be
711-
* stuck in here without loaded event!
750+
* When no such *.js existed, IE will be
751+
* stuck here without loaded event!
712752
*/
753+
/*
713754
if ((window.location.protocol != "file:"
714755
&& script.src.indexOf ("file:") != 0)
715756
|| this.readyState != "loading") {
716757
return;
717758
}
759+
*/
760+
if (fss[path] == null) {
761+
var fun = function () {
762+
var path = arguments.callee.path;
763+
// next time in "loading" state won't get waiting!
764+
ClazzLoader.failedScripts[path] = 0;
765+
ClazzLoader.loadedScripts[path] = false;
766+
// Take another try!
767+
ClazzLoader.loadScript (path);
768+
};
769+
fun.path = path;
770+
// consider 30 seconds available after failing!
771+
fhs[path] = window.setTimeout (fun, 15000);
772+
return;
773+
}
774+
if (fss[path] == 1) {
775+
return;
776+
}
777+
}
778+
if (fhs[path] != null) {
779+
window.clearTimeout (fhs[path]);
780+
fhs[path] = null;
781+
}
782+
if (state == "loaded" && !ClazzLoader.isInnerLoaded) {
783+
if (fss[path] == null || fss[path] == 0) {
784+
// silently take another try for bad network
785+
fss[path] = 1;
786+
// log ("reloading ... " + path);
787+
ClazzLoader.loadedScripts[path] = false;
788+
ClazzLoader.loadScript (path);
789+
return;
790+
} else {
791+
alert ("[Java2Script] Error in loading " + path + "!");
792+
}
718793
}
719-
var path = arguments.callee.path;
720794
ClazzLoader.scriptLoaded (path);
721795
// Unset onreadystatechange, leaks mem in IE
722796
this.onreadystatechange = null;
@@ -730,11 +804,14 @@ ClazzLoader.loadScript = function (file) {
730804
};
731805
script.onreadystatechange.path = file;
732806
}
807+
ClazzLoader.isInnerLoaded = false;
733808
// Add script DOM element to document tree
734-
document.getElementsByTagName ("HEAD")[0].appendChild (script);
809+
head.appendChild (script);
735810
ClazzLoader.scriptLoading (file);
736811
};
737812

813+
ClazzLoader.isFirstScript = true;
814+
738815
/* protected */
739816
ClazzLoader.isResourceExisted = function (id, path, base) {
740817
if (id != null && document.getElementById (id) != null) {
@@ -1238,12 +1315,21 @@ ClazzLoader.searchClassArray = function (arr, rnd, status) {
12381315
return null;
12391316
};
12401317

1318+
/**
1319+
* This variable is used to mark that *.js is correctly loaded.
1320+
* In IE, ClazzLoader has defects to detect whether a *.js is correctly
1321+
* loaded or not, so inner loading mark is used for detecting.
1322+
*/
1323+
/* private */
1324+
ClazzLoader.isInnerLoaded = false;
1325+
12411326
/**
12421327
* This method will be called in almost every *.js generated by Java2Script
12431328
* compiler.
12441329
*/
12451330
/* protected */
12461331
ClazzLoader.load = function (musts, clazz, optionals, declaration) {
1332+
ClazzLoader.isInnerLoaded = true;
12471333
if (clazz instanceof Array) {
12481334
ClazzLoader.unwrapArray (clazz);
12491335
for (var i = 0; i < clazz.length; i++) {

0 commit comments

Comments
 (0)