assimp icon indicating copy to clipboard operation
assimp copied to clipboard

kotlin.KotlinNullPointerException when importing step file

Open jimmyd-be opened this issue 6 years ago • 3 comments

I'm creating a POC for visualizing STP files in a Java application. I try to import the step file using the Importer().readFile() method and this gives a

Exception in thread "main" kotlin.KotlinNullPointerException
	at uno.kotlin.UtilKt.getUrl(util.kt:22)
	at uno.kotlin.UtilKt.getUri(util.kt:21)
	at assimp.Importer.readFile(Importer.kt:308)

This by only set this line of code: AiScene scene = new Importer().readFile(fileName, 0); fileName variable is the full path to the stp file.

jimmyd-be avatar Nov 05 '18 07:11 jimmyd-be

I don't think we have an Importer implemented for step files (yet). I can't however recreate the NPE. What version of assimp are you using? AFAIK (and according to my tests) you should see a kotlin.NotImplementedError which I just changed to a proper error message.

Wasabi375 avatar Nov 05 '18 10:11 Wasabi375

Hi there! The issue here I am also seeing, and it is independent of the file you are importing: The reason it is occuring is that String.url and String.uri are defined as

val String.uri get() = url.toURI()!!
val String.url get() = ClassLoader.getSystemResource(this)!!

This in turn means that you are trying to use the system classloader to get the path to the file, which only works if the file is actually in the class path -- and that is most likely not the case if the file name comes e.g. from a file open dialog -- otherwise getSystemResource() will return null, which is seen here.

Getting from a String to an URI/URL in Java is however not super-straightforward, and you need to take the different platforms into consideration. One way to solve this is to convert the String to a Path, and get the URL/URI from that. We are doing that in scenery in this way:

fun getPath(path: URI): Path {
            return try {
                Paths.get(path)
            } catch (e: FileSystemNotFoundException) {
                val env: Map<String, Any> = emptyMap()
                try {
                    val fs = FileSystems.newFileSystem(path, env)

                    fs.provider().getPath(path)
                } catch(pnfe: ProviderNotFoundException) {
                    FileSystems.getDefault().getPath(path.toString())
                }
            } catch (e : IllegalArgumentException) {
                // handle the case when no scheme is given
                when(ExtractsNatives.getPlatform()) {
                    // on macOS and Linux, we'll just use the default file system and hand over the scheme-less path
                    ExtractsNatives.Platform.MACOS,
                    ExtractsNatives.Platform.LINUX -> FileSystems.getDefault().getPath(path.toString())
                    // on Windows, a leading slash is added, which we remove
                    ExtractsNatives.Platform.WINDOWS -> FileSystems.getDefault().getPath(path.toString().substring(1))
                    else -> {
                        throw IllegalStateException("Don't know how to sanitize path $path on unknown platform.")
                    }
                }
            }
        }

skalarproduktraum avatar Apr 06 '19 13:04 skalarproduktraum

Woops, your right. I'll look into it. Seems like there are still some more temporary utility function used. Thanks for the code snippet.

Wasabi375 avatar Apr 06 '19 21:04 Wasabi375