# Load Jython Classes on Startup

**URL:** <https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585>\
**Category:** Ignition\
**Created:** [August 29, 2022, 11:25pm UTC](https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585 "2022-08-29T23:25:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jonathan](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jonathan](https://forum.inductiveautomation.com/u/Jonathan)\
**Post date:** [August 29, 2022, 11:25pm UTC](https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585/1 "2022-08-29T23:25:37Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 30, 2022, 12:01am UTC](https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585/2 "2022-08-30T00:01:05Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 30, 2022, 12:52am UTC](https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585/3 "2022-08-30T00:52:01Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Jonathan](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jonathan](https://forum.inductiveautomation.com/u/Jonathan)\
**Post date:** [August 30, 2022, 6:24pm UTC](https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585/4 "2022-08-30T18:24:54Z")

</div>

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

```auto
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

```auto
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](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/8/88e40e34fa2c0358bd85c5cdb54ddd0cfc0c3ac5.png)

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.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 30, 2022, 6:34pm UTC](https://forum.inductiveautomation.com/t/load-jython-classes-on-startup/63585/5 "2022-08-30T18:34:05Z")

</div>

> [@Jonathan](#):
>
> It appears to me that the project library scripts do not load until a class is referenced in them.

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:

> [@\[IGN-5244\]Persist Python Class Object](https://forum.inductiveautomation.com/t/ign-5244-persist-python-class-object/30498):
>
> I am working in Perspective, but this probably applies to other modules as well. I have created user defined classes in the project scripts and I am instantiating them from a view in Perspective. Is there a place I can persist the instance of the object for use between events by the user? Right now I have it serializing to a property on the view, but when I want to work with the object again I have to de-serialize the object in order to work with it again. Having to write custom de-serialize me…

Edit: Bug found, work-around developed:

> [@Project Library Script Initialization Races](https://forum.inductiveautomation.com/t/project-library-script-initialization-races/98636):
>
> Are you annoyed by pseudo-random breakage in Ignition project library scripting? Odd top-level constants being garbled, or operations in the top level that have side effects running twice? Or more? Not happening much, but always around project edits, and sometimes even on gateway restart? Yeah, me too. frowning_face Poking around under the hood back in the spring, for a module development task, I ran across some problematic IA bytecode and pinged some people. But it went nowhere, as I co…
