Load Jython Classes on Startup

Is there a way to have a project load/import all the Jython classes in the project library on project startup?

What behavior are trying to produce? Are you looking for persistent objects or are there functions that you are expecting to be accessible that aren’t?

What classes/functions/objects aren’t ?

(Project library scripts are pre-loaded into script environments automatically. No need to import. Actually, importing a project script can cause subtle bugs when project hierarchies are saved/reloaded.)

Just refer to project library classes/functions/objects by their fully qualified name wherever you need them. Without any import.

It appears to me that the project library scripts do not load until a class is referenced in them. I am not sure if load is the correct word or not. If I place info loggers in my script files I can see they do not load until I reference a class in the file.

When I reference a class a second time the script file does not load a second time it seems to be loaded/cached(?).

Waiting until a class is referenced seems to be a potential problem when I have two separate threads referencing the same class. The threads will try and both load the same script file and can lead to a mismatch of the same class.

My work around to this problem would be to have the project load all the script files with classes before anything referenced them. I do not want to manually have to add this to the gateway startup script so I was hoping there was a way to do this dynamically in code.

Here is an example where I am able to reproduce:

filename: testClass

logger = system.util.getLogger("testClass")

logger.info("testClass file loaded")
print "testClass file loaded"

class TestClass(object):
	logger.info("TestClass class loaded")
	print "TestClass class loaded"
	def __init__(self):
		self.a= "A"

filename: testRun

from java.util.concurrent import LinkedBlockingQueue

#uncomment testClass.TestClass to pre load script file. This will fix the issue of possible different class Ids
#testClass.TestClass

filePath = "c:/temp/classIds.txt"

def runTest():	
	queue1 = LinkedBlockingQueue()
	queue2 = LinkedBlockingQueue()
	
	system.file.writeFile(filePath, "", False)
	
	def doAsync1(queue1=queue1):				
		queue1.take()
		system.file.writeFile(filePath, "queue1 id(testClass.TestClass)=%s\n" % (id(testClass.TestClass)), True)
	
	def doAsync2(queue2=queue2):
		queue2.take()
		system.file.writeFile(filePath, "queue2 id(testClass.TestClass)=%s\n" % (id(testClass.TestClass)), True)
		
	print system.util.invokeAsynchronous(doAsync1)
	print system.util.invokeAsynchronous(doAsync2)
	
	queue1.put(1)
	queue2.put(2)

Run: testRun.runTest()

Here you can see the output in my test file that the ids of the same class does not match.
image

If you run it from the script console you have to reset the console to in between runs. Also the ids are not always different and I think this is because it is a race condition. I usually can get it to do it every few resets of the console.

If you run this from the gateway scope you have to make a change that causes the project to restart in between runs.

Any named object, actually. And once-through is intended behavior, like import. Cross-thread dependencies are not supposed to impact this import mechanism (there's an import lock), but maybe IA has introduced a bug here.

Consider using a global lock object to ensure initialization doesn't happen in parallel (via system.util.getGlobals() or the similar system.util.persistent() from my LifeCycle module).

You may recall participating in this topic:

Edit: Bug found, work-around developed: