[Geoserver-devel] Interesting (maybe) observation about test startup times

Hi,
I was looking at a test starting up with verbose logging and this caugth my attention:

28 gen 15:51:01 INFO [ows.OWSHandlerMapping] - Mapped URL path [/wfs/*] onto handler ‘dispatcher’
28 gen 15:51:01 INFO [ows.OWSHandlerMapping] - Mapped URL path [/TestWfsPost] onto handler ‘wfsTestServlet’
28 gen 15:51:01 INFO [ows.OWSHandlerMapping] - Mapped URL path [/wfs] onto handler ‘dispatcher’
28 gen 15:51:01 DEBUG [geotools.xml] - building schema for schema: http://www.opengis.net/gml/3.2
28 gen 15:51:04 INFO [ows.OWSHandlerMapping] - Mapped URL path [/ows/] onto handler ‘dispatcher’
28 gen 15:51:04 INFO [ows.OWSHandlerMapping] - Mapped URL path [/ows] onto handler ‘dispatcher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/www/
] onto handler ‘filePublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/styles/] onto handler ‘filePublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/j_spring_security_check] onto handler ‘classpathPublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/j_acegi_security_check] onto handler ‘classpathPublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/schemas/
] onto handler ‘classpathPublisher’

Uh, 3 seconds spent building schemas? Maybe it’s not only the 3.2 schema, and maybe there
is something else that is not logging anything, but still GML schemas are indeed large to build.

Is that something we really need to do at each startup? E.g., WMS tests would not actually
need that

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


Hmmm… nothing comes to mind as to why we have to load the schema on startup. I guess I would put a breakpoint in the org.geotools.gml3.v3_2.GML.buildSchema() method and see why and where its being triggered from, to see if it can be avoided.

···

On Mon, Jan 28, 2013 at 7:56 AM, Andrea Aime <andrea.aime@anonymised.com> wrote:

Hi,
I was looking at a test starting up with verbose logging and this caugth my attention:

28 gen 15:51:01 INFO [ows.OWSHandlerMapping] - Mapped URL path [/wfs/*] onto handler ‘dispatcher’
28 gen 15:51:01 INFO [ows.OWSHandlerMapping] - Mapped URL path [/TestWfsPost] onto handler ‘wfsTestServlet’
28 gen 15:51:01 INFO [ows.OWSHandlerMapping] - Mapped URL path [/wfs] onto handler ‘dispatcher’
28 gen 15:51:01 DEBUG [geotools.xml] - building schema for schema: http://www.opengis.net/gml/3.2
28 gen 15:51:04 INFO [ows.OWSHandlerMapping] - Mapped URL path [/ows/] onto handler ‘dispatcher’
28 gen 15:51:04 INFO [ows.OWSHandlerMapping] - Mapped URL path [/ows] onto handler ‘dispatcher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/www/
] onto handler ‘filePublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/styles/] onto handler ‘filePublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/j_spring_security_check] onto handler ‘classpathPublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/j_acegi_security_check] onto handler ‘classpathPublisher’
28 gen 15:51:04 INFO [handler.SimpleUrlHandlerMapping] - Mapped URL path [/schemas/
] onto handler ‘classpathPublisher’

Uh, 3 seconds spent building schemas? Maybe it’s not only the 3.2 schema, and maybe there
is something else that is not logging anything, but still GML schemas are indeed large to build.

Is that something we really need to do at each startup? E.g., WMS tests would not actually
need that

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it



Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only – learn more at:
http://p.sf.net/sfu/learnnow-d2d


Geoserver-devel mailing list
Geoserver-devel@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel


Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

On Mon, Jan 28, 2013 at 4:21 PM, Justin Deoliveira <jdeolive@anonymised.com> wrote:

Hmmm… nothing comes to mind as to why we have to load the schema on startup. I guess I would put a breakpoint in the org.geotools.gml3.v3_2.GML.buildSchema() method and see why and where its being triggered from, to see if it can be avoided.

Hmm, it’s coming from here:

// Trigger immediate construction of full GML schema before dependencies are constructed, to
// handle cyclic dependencies. See GEOT-3327.
try {
getSchema();
} catch (IOException e) {
throw new RuntimeException(e);
}

http://jira.codehaus.org/browse/GEOT-3327

Hmm… is this related to the ISO schemas that GML depends onto?
Now they are separate from GML on the opengis site:
http://schemas.opengis.net/iso/19139/20070417/

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


On Mon, Jan 28, 2013 at 6:17 PM, Andrea Aime <andrea.aime@anonymised.com> wrote:

On Mon, Jan 28, 2013 at 4:21 PM, Justin Deoliveira <jdeolive@anonymised.com> wrote:

Hmmm… nothing comes to mind as to why we have to load the schema on startup. I guess I would put a breakpoint in the org.geotools.gml3.v3_2.GML.buildSchema() method and see why and where its being triggered from, to see if it can be avoided.

Hmm, it’s coming from here:

// Trigger immediate construction of full GML schema before dependencies are constructed, to
// handle cyclic dependencies. See GEOT-3327.
try {
getSchema();
} catch (IOException e) {
throw new RuntimeException(e);
}

Ah, forgot one bit, the above method is called as we initialize FeatureTypeSchemaBuilder:

Thread [main] (Suspended (breakpoint at line 2732 in GML))
owns: GML (id=57)
owns: ConcurrentHashMap<K,V> (id=58)
owns: ConcurrentHashMap<K,V> (id=59)
owns: Object (id=60)
GML.buildSchema() line: 2732
GML(XSD).getSchema() line: 232
GML.() line: 71
GML.() line: 55
FeatureTypeSchemaBuilder$GML32.createTypeMappingProfile() line: 960
FeatureTypeSchemaBuilder$GML32(FeatureTypeSchemaBuilder$GML3).(GeoServer) line: 895
FeatureTypeSchemaBuilder$GML32.(GeoServer) line: 944
XmlSchemaEncoder$V20.(GeoServer) line: 121
NativeConstructorAccessorImpl.newInstance0(Constructor, Object) line: not available [native method]
NativeConstructorAccessorImpl.newInstance(Object) line: 39
DelegatingConstructorAccessorImpl.newInstance(Object) line: 27
Constructor.newInstance(Object…) line: 513
BeanUtils.instantiateClass(Constructor, Object…) line: 147
CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory, Constructor<?>, Object) line: 110
ConstructorResolver.autowireConstructor(String, RootBeanDefinition, Constructor, Object) line: 280
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).autowireConstructor(String, RootBeanDefinition, Constructor, Object) line: 1035
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object) line: 939
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object) line: 485
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object) line: 456
AbstractBeanFactory$1.getObject() line: 294
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 225
DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object, boolean) line: 291
DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 193
DefaultListableBeanFactory.preInstantiateSingletons() line: 585
GeoServerTestApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 913
GeoServerTestApplicationContext(AbstractApplicationContext).refresh() line: 464
GetFeatureTest(GeoServerSystemTestSupport).setUp(SystemTestData) line: 201
GetFeatureTest(GeoServerSystemTestSupport).setUp(TestData) line: 1
GetFeatureTest(GeoServerBaseTestSupport).doSetup() line: 150
NativeMethodAccessorImpl.invoke0(Method, Object, Object) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object) line: 25
Method.invoke(Object, Object…) line: 597
FrameworkMethod$1.runReflectiveCall() line: 45
FrameworkMethod$1(ReflectiveCallable).run() line: 15
FrameworkMethod.invokeExplosively(Object, Object…) line: 42
RunBefores.evaluate() line: 27
RunAfters.evaluate() line: 30
RunRules.evaluate() line: 18
BlockJUnit4ClassRunner(ParentRunner).runLeaf(Statement, Description, RunNotifier) line: 263
BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 68
BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 47
ParentRunner$3.run() line: 231
ParentRunner$1.schedule(Runnable) line: 60
BlockJUnit4ClassRunner(ParentRunner).runChildren(RunNotifier) line: 229
ParentRunner.access$000(ParentRunner, RunNotifier) line: 50
ParentRunner$2.evaluate() line: 222
RunBefores.evaluate() line: 28
RunAfters.evaluate() line: 30
BlockJUnit4ClassRunner(ParentRunner).run(RunNotifier) line: 300
JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 50
TestExecution.run(ITestReference) line: 38
RemoteTestRunner.runTests(String, String, TestExecution) line: 467
RemoteTestRunner.runTests(TestExecution) line: 683
RemoteTestRunner.run() line: 390
RemoteTestRunner.main(String) line: 197

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


Hmmm… i was afraid it would be one of these nasty issues. I will have to delegate on Ben on this one. Perhaps the recent changes to the ogc schemas (or perhaps just gml 3.2) has made this one obsolete.

···

On Mon, Jan 28, 2013 at 10:20 AM, Andrea Aime <andrea.aime@anonymised.com> wrote:

On Mon, Jan 28, 2013 at 6:17 PM, Andrea Aime <andrea.aime@anonymised.com> wrote:

On Mon, Jan 28, 2013 at 4:21 PM, Justin Deoliveira <jdeolive@anonymised.com1…> wrote:

Hmmm… nothing comes to mind as to why we have to load the schema on startup. I guess I would put a breakpoint in the org.geotools.gml3.v3_2.GML.buildSchema() method and see why and where its being triggered from, to see if it can be avoided.

Hmm, it’s coming from here:

// Trigger immediate construction of full GML schema before dependencies are constructed, to
// handle cyclic dependencies. See GEOT-3327.
try {
getSchema();
} catch (IOException e) {
throw new RuntimeException(e);
}

Ah, forgot one bit, the above method is called as we initialize FeatureTypeSchemaBuilder:

Thread [main] (Suspended (breakpoint at line 2732 in GML))
owns: GML (id=57)
owns: ConcurrentHashMap<K,V> (id=58)
owns: ConcurrentHashMap<K,V> (id=59)
owns: Object (id=60)
GML.buildSchema() line: 2732
GML(XSD).getSchema() line: 232
GML.() line: 71
GML.() line: 55
FeatureTypeSchemaBuilder$GML32.createTypeMappingProfile() line: 960
FeatureTypeSchemaBuilder$GML32(FeatureTypeSchemaBuilder$GML3).(GeoServer) line: 895
FeatureTypeSchemaBuilder$GML32.(GeoServer) line: 944
XmlSchemaEncoder$V20.(GeoServer) line: 121
NativeConstructorAccessorImpl.newInstance0(Constructor, Object) line: not available [native method]
NativeConstructorAccessorImpl.newInstance(Object) line: 39
DelegatingConstructorAccessorImpl.newInstance(Object) line: 27
Constructor.newInstance(Object…) line: 513
BeanUtils.instantiateClass(Constructor, Object…) line: 147
CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory, Constructor<?>, Object) line: 110
ConstructorResolver.autowireConstructor(String, RootBeanDefinition, Constructor, Object) line: 280
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).autowireConstructor(String, RootBeanDefinition, Constructor, Object) line: 1035
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object) line: 939
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object) line: 485
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object) line: 456
AbstractBeanFactory$1.getObject() line: 294
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 225
DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object, boolean) line: 291
DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 193
DefaultListableBeanFactory.preInstantiateSingletons() line: 585
GeoServerTestApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 913
GeoServerTestApplicationContext(AbstractApplicationContext).refresh() line: 464
GetFeatureTest(GeoServerSystemTestSupport).setUp(SystemTestData) line: 201
GetFeatureTest(GeoServerSystemTestSupport).setUp(TestData) line: 1
GetFeatureTest(GeoServerBaseTestSupport).doSetup() line: 150
NativeMethodAccessorImpl.invoke0(Method, Object, Object) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object) line: 25
Method.invoke(Object, Object…) line: 597
FrameworkMethod$1.runReflectiveCall() line: 45
FrameworkMethod$1(ReflectiveCallable).run() line: 15
FrameworkMethod.invokeExplosively(Object, Object…) line: 42
RunBefores.evaluate() line: 27
RunAfters.evaluate() line: 30
RunRules.evaluate() line: 18
BlockJUnit4ClassRunner(ParentRunner).runLeaf(Statement, Description, RunNotifier) line: 263
BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 68
BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 47
ParentRunner$3.run() line: 231
ParentRunner$1.schedule(Runnable) line: 60
BlockJUnit4ClassRunner(ParentRunner).runChildren(RunNotifier) line: 229
ParentRunner.access$000(ParentRunner, RunNotifier) line: 50
ParentRunner$2.evaluate() line: 222
RunBefores.evaluate() line: 28
RunAfters.evaluate() line: 30
BlockJUnit4ClassRunner(ParentRunner).run(RunNotifier) line: 300
JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 50
TestExecution.run(ITestReference) line: 38
RemoteTestRunner.runTests(String, String, TestExecution) line: 467
RemoteTestRunner.runTests(TestExecution) line: 683
RemoteTestRunner.run() line: 390
RemoteTestRunner.main(String) line: 197

Cheers

Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it



Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

On Tue, Jan 29, 2013 at 1:10 AM, Justin Deoliveira <jdeolive@anonymised.com> wrote:

Hmmm… i was afraid it would be one of these nasty issues. I will have to delegate on Ben on this one. Perhaps the recent changes to the ogc schemas (or perhaps just gml 3.2) has made this one obsolete.

Yep… Ben? :slight_smile: It seems we are paying quite the price for this workaound in terms of testing times.

About the OGC schema upgrade… I’m stuck with failures, sent a mail to geotools, got no
significant suggestions on how to proceed

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


On 29/01/13 15:21, Andrea Aime wrote:

On Tue, Jan 29, 2013 at 1:10 AM, Justin Deoliveira <jdeolive@anonymised.com
<mailto:jdeolive@anonymised.com>> wrote:
    Hmmm... i was afraid it would be one of these nasty issues. I will
    have to delegate on Ben on this one. Perhaps the recent changes to
    the ogc schemas (or perhaps just gml 3.2) has made this one obsolete.
Yep.. Ben? :slight_smile: It seems we are paying quite the price for this workaound
in terms of testing times.

I doubt that this is obsolete as GML 3.2 still has cyclic type definitions and care must be taken in the order of construction. I agree that it would be good to defer schema construction until they are needed, as this would save both time and memory in the case that they are not. I wonder if FeatureTypeSchemaBuilder or whatever is calling it could be lazier?

Kind regards,

--
Ben Caradoc-Davies <Ben.Caradoc-Davies@anonymised.com>
Software Engineer
CSIRO Earth Science and Resource Engineering
Australian Resources Research Centre

The WFS applicationContext.xml explicitly references XmlSchemaEncoder.V20, which instantiates FeatureTypeSchemaBuilder.GML32 in its constructor.

Can Spring be persuaded to load XmlSchemaEncoder.V20 lazily?

On 29/01/13 01:20, Andrea Aime wrote:

FeatureTypeSchemaBuilder$GML32.<init>(GeoServer) line: 944
XmlSchemaEncoder$V20.<init>(GeoServer) line: 121
NativeConstructorAccessorImpl.newInstance0(Constructor, Object) line:
not available [native method]

--
Ben Caradoc-Davies <Ben.Caradoc-Davies@anonymised.com>
Software Engineer
CSIRO Earth Science and Resource Engineering
Australian Resources Research Centre

Hmmm… as long as there is nothing depending on it (which there shouldn’t be) it should be lazily loadable as it will be created the first time the REsponse extension point is processed. Which I actually won’t help system tests since they will typically go through the dispatcher, meaning that the response extension point will be triggered. Sigh…

I guess we could by default remove the relevant bean configurations from the spring context in the system test setup, and have any fo the wfs tests that require them to keep them enabled.

···

On Tue, Jan 29, 2013 at 2:44 AM, Ben Caradoc-Davies <Ben.Caradoc-Davies@anonymised.com> wrote:

The WFS applicationContext.xml explicitly references XmlSchemaEncoder.V20, which instantiates FeatureTypeSchemaBuilder.GML32 in its constructor.

Can Spring be persuaded to load XmlSchemaEncoder.V20 lazily?

On 29/01/13 01:20, Andrea Aime wrote:

FeatureTypeSchemaBuilder$GML32.(GeoServer) line: 944
XmlSchemaEncoder$V20.(GeoServer) line: 121
NativeConstructorAccessorImpl.newInstance0(Constructor, Object) line:
not available [native method]


Ben Caradoc-Davies Ben.Caradoc-Davies@anonymised.com
Software Engineer
CSIRO Earth Science and Resource Engineering
Australian Resources Research Centre


Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

I will also have a deeper look at whether the schemas need to be loaded at this point, but I will not be able to do so for several weeks.

Kind regards,
Ben.

On 30/01/13 12:15, Justin Deoliveira wrote:

Hmmm... as long as there is nothing depending on it (which there
shouldn't be) it should be lazily loadable as it will be created the
first time the REsponse extension point is processed. Which I actually
won't help system tests since they will typically go through the
dispatcher, meaning that the response extension point will be triggered.
Sigh....

I guess we could by default remove the relevant bean configurations from
the spring context in the system test setup, and have any fo the wfs
tests that require them to keep them enabled.

On Tue, Jan 29, 2013 at 2:44 AM, Ben Caradoc-Davies
<Ben.Caradoc-Davies@anonymised.com <mailto:Ben.Caradoc-Davies@anonymised.com>> wrote:

    The WFS applicationContext.xml explicitly references
    XmlSchemaEncoder.V20, which instantiates
    FeatureTypeSchemaBuilder.GML32 in its constructor.

    Can Spring be persuaded to load XmlSchemaEncoder.V20 lazily?

    On 29/01/13 01:20, Andrea Aime wrote:

        FeatureTypeSchemaBuilder$__GML32.<init>(GeoServer) line: 944
        XmlSchemaEncoder$V20.<init>(__GeoServer) line: 121
        NativeConstructorAccessorImpl.__newInstance0(Constructor,
        Object) line:
        not available [native method]

    --
    Ben Caradoc-Davies <Ben.Caradoc-Davies@anonymised.com>
    Software Engineer
    CSIRO Earth Science and Resource Engineering
    Australian Resources Research Centre

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

--
Ben Caradoc-Davies <Ben.Caradoc-Davies@anonymised.com>
Software Engineer
CSIRO Earth Science and Resource Engineering
Australian Resources Research Centre