diff --git a/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/Jars.kt b/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/Jars.kt index 258a9782e..ab04546fa 100644 --- a/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/Jars.kt +++ b/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/Jars.kt @@ -17,6 +17,7 @@ package org.jacodb.impl.fs import jetbrains.exodus.util.LightByteArrayOutputStream +import org.jacodb.impl.util.asSequence import java.io.InputStream import java.io.OutputStream import java.util.jar.Attributes @@ -43,9 +44,9 @@ class JarFacade(private val runtimeVersion: Int, private val getter: () -> JarFi getter().use { jarFile -> isJmod = jarFile?.name?.endsWith(".jmod") ?: false isMultiReleaseEnabledInManifest = jarFile?.manifest?.mainAttributes?.getValue(MULTI_RELEASE).toBoolean() - entries = jarFile?.entries()?.toList()?.filter { + entries = jarFile?.entries()?.asSequence()?.filter { it.name.endsWith(".class") && !it.name.contains("module-info") - }?.associateBy { it.name } + }?.associate { it.name to JarEntry(it) } } } @@ -85,8 +86,8 @@ class JarFacade(private val runtimeVersion: Int, private val getter: () -> JarFi val jarFile = getter() ?: return emptyMap() return jarFile.use { val buffer = ByteArray(DEFAULT_BUFFER_SIZE * 8) - classes.map { it.key to jarFile.getInputStream(it.value).use { it.readBytes(buffer) } } - }.toMap() + classes.entries.associate { it.key to jarFile.getInputStream(it.value).use { it.readBytes(buffer) } } + } } } diff --git a/jacodb-core/src/main/kotlin/org/jacodb/impl/util/SequenceUtil.kt b/jacodb-core/src/main/kotlin/org/jacodb/impl/util/SequenceUtil.kt index e148c4f12..6a6fbe015 100644 --- a/jacodb-core/src/main/kotlin/org/jacodb/impl/util/SequenceUtil.kt +++ b/jacodb-core/src/main/kotlin/org/jacodb/impl/util/SequenceUtil.kt @@ -16,6 +16,18 @@ package org.jacodb.impl.util +import java.util.* + inline fun Sequence(crossinline it: () -> Iterable): Sequence = object : Sequence { override fun iterator(): Iterator = it().iterator() +} + +fun Enumeration?.asSequence(): Sequence { + if (this == null) return emptySequence() + return object : Sequence { + override fun iterator(): Iterator = object : Iterator { + override fun hasNext() = this@asSequence.hasMoreElements() + override fun next(): T = this@asSequence.nextElement() + } + } } \ No newline at end of file diff --git a/jacodb-core/src/test/kotlin/org/jacodb/testing/JarFacadeTest.kt b/jacodb-core/src/test/kotlin/org/jacodb/testing/JarFacadeTest.kt index 97b1f0f95..708f299da 100644 --- a/jacodb-core/src/test/kotlin/org/jacodb/testing/JarFacadeTest.kt +++ b/jacodb-core/src/test/kotlin/org/jacodb/testing/JarFacadeTest.kt @@ -16,9 +16,14 @@ package org.jacodb.testing +import kotlinx.coroutines.runBlocking +import org.jacodb.impl.JcRamErsSettings import org.jacodb.impl.fs.JarFacade import org.jacodb.impl.fs.parseRuntimeVersion -import org.junit.jupiter.api.Assertions.* +import org.jacodb.impl.jacodb +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledOnJre import org.junit.jupiter.api.condition.JRE @@ -93,4 +98,15 @@ class JarFacadeTest { assertTrue(javaBase.classes.contains("java.lang.String")) assertNotNull(javaBase.inputStreamOf("java.lang.String")) } + + @Test + fun `load bouncycastle`(): Unit = runBlocking { + val jar = cookJar("https://repo1.maven.org/maven2/org/bouncycastle/bcpg-jdk18on/1.78.1/bcpg-jdk18on-1.78.1.jar") + val db = jacodb { + persistenceImpl(JcRamErsSettings) + loadByteCode(listOf(jar.toFile())) + }.apply { awaitBackgroundJobs() } + val cp = db.classpath(listOf(jar.toFile())) + assertTrue(cp.locations.flatMap { location -> location.classes.values }.isNotEmpty()) + } } \ No newline at end of file diff --git a/jacodb-core/src/test/kotlin/org/jacodb/testing/persistence/incrementality/IncrementalDbTest.kt b/jacodb-core/src/test/kotlin/org/jacodb/testing/persistence/incrementality/IncrementalDbTest.kt index fcffc76a5..4299dd01c 100644 --- a/jacodb-core/src/test/kotlin/org/jacodb/testing/persistence/incrementality/IncrementalDbTest.kt +++ b/jacodb-core/src/test/kotlin/org/jacodb/testing/persistence/incrementality/IncrementalDbTest.kt @@ -19,15 +19,12 @@ package org.jacodb.testing.persistence.incrementality import kotlinx.coroutines.runBlocking import org.jacodb.api.jvm.ext.findClass import org.jacodb.testing.WithDb +import org.jacodb.testing.cookJar +import org.jacodb.testing.createTempJar import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test -import java.net.URL import java.nio.file.Files -import java.nio.file.Files.createDirectories -import java.nio.file.Path import java.nio.file.StandardCopyOption -import kotlin.io.path.Path -import kotlin.io.path.createTempDirectory class IncrementalDbTest { @@ -55,16 +52,4 @@ class IncrementalDbTest { db.awaitBackgroundJobs() Assertions.assertTrue(bc1 contentEquals cp.findClass("com.github.penemue.keap.PriorityQueue").bytecode()) } - - private fun cookJar(link: String): Path { - val url = URL(link) - val result = createTempJar(url.file) - Files.copy(url.openStream(), result, StandardCopyOption.REPLACE_EXISTING) - return result - } - - private fun createTempJar(name: String) = - Path(createTempDirectory("jcdb-temp-jar").toString(), name).also { - createDirectories(it.parent) - } } \ No newline at end of file diff --git a/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/Jars.kt b/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/Jars.kt new file mode 100644 index 000000000..69e891b64 --- /dev/null +++ b/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/Jars.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2022 UnitTestBot contributors (utbot.org) + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jacodb.testing + +import java.net.URL +import java.nio.file.Files +import java.nio.file.Files.createDirectories +import java.nio.file.Path +import java.nio.file.StandardCopyOption +import kotlin.io.path.Path +import kotlin.io.path.createTempDirectory + +fun cookJar(link: String): Path { + val url = URL(link) + val result = createTempJar(url.file) + Files.copy(url.openStream(), result, StandardCopyOption.REPLACE_EXISTING) + return result +} + +fun createTempJar(name: String) = + Path(createTempDirectory("jcdb-temp-jar").toString(), name).also { + createDirectories(it.parent) + } \ No newline at end of file