Repository navigation
warning: argument -classpath is passed multiple times. Only the last value will be used #171
Description
I am trying to start the kscript in interactive mode with some dependencies and my local code. Dependencies are defined with gradle-style locators. I would like to reference my code in the classpath. Whatever I use (the classpath referencing local folder or library jar), I get the "warning: argument -classpath is passed multiple times. Only the last value will be used".
It seems to me that it is not possible to use //DEPS and //KOTLIN_OPTS at the same time. Is this a bug or a feature? I would definitely like to have //DEPS and additionally reference my local code with -classpath. I think kscript should merge these two into one -classpath sent to the kotlin executable.
My use case is to start interactive REPL for the kotlin spring library.
When I have following init.kts:
//DEPS org.springframework.boot:spring-boot-starter:2.0.4.RELEASE org.springframework.boot:spring-boot:2.0.4.RELEASE org.springframework:spring-core:5.0.8.RELEASE org.springframework:spring-aop:5.0.8.RELEASE org.springframework:spring-beans:5.0.8.RELEASE org.springframework:spring-beans:5.0.8.RELEASE org.springframework:spring-core:5.0.8.RELEASE org.springframework.boot:spring-boot-autoconfigure:2.0.4.RELEASE org.springframework.boot:spring-boot-starter-logging:2.0.4.RELEASE ch.qos.logback:logback-classic:1.2.3 ch.qos.logback:logback-core:1.2.3 org.apache.logging.log4j:log4j-to-slf4j:2.10.0 org.slf4j:slf4j-api:1.7.25 javax.annotation:javax.annotation-api:1.3.2 org.springframework:spring-core:5.0.8.RELEASE com.fasterxml.jackson.module:jackson-module-kotlin:2.9.6 com.fasterxml.jackson.core:jackson-databind:2.9.6 com.fasterxml.jackson.core:jackson-annotations:2.9.0 com.fasterxml.jackson.core:jackson-annotations:2.9.0 org.jetbrains.kotlin:kotlin-stdlib-common:1.2.70 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.70 org.jetbrains.kotlin:kotlin-stdlib:1.2.70 org.jetbrains.kotlin:kotlin-reflect:1.2.70 org.slf4j:slf4j-api:1.7.25 ch.qos.logback:logback-classic:1.2.3 ch.qos.logback:logback-core:1.2.3 commons-io:commons-io:2.6 org.springframework:spring-web:5.1.0.RELEASE org.springframework:spring-beans:5.1.0.RELEASE com.madgag.spongycastle:core:1.51.0.0 com.google.protobuf:protobuf-java:2.6.1 com.google.guava:guava:18.0 com.google.code.findbugs:jsr305:2.0.1 net.jcip:jcip-annotations:1.0 com.lambdaworks:scrypt:1.4.0 org.bitcoinj:orchid:1.2.1 com.google.guava:guava:18.0 com.squareup.okhttp:okhttp:2.7.2
//KOTLIN_OPTS -cp build/libs/myproject.jar
And I try to start the kscript interactive REPL I get following warning:
$ kscript --interactive init.kts
[kscript] Creating REPL from init.kts
warning: argument -classpath is passed multiple times. Only the last value will be used: /Users/zlatkoc/.m2/repository/org/springframework/boot/spring-boot-starter/2.0.4.RELEASE/spring-boot-starter-2.0.4.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/yaml/snakeyaml/1.19/snakeyaml-1.19.jar:/Users/zlatkoc/.m2/repository/org/springframework/boot/spring-boot/2.0.4.RELEASE/spring-boot-2.0.4.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-context/5.0.8.RELEASE/spring-context-5.0.8.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-expression/5.0.8.RELEASE/spring-expression-5.0.8.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-core/5.0.8.RELEASE/spring-core-5.0.8.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-jcl/5.0.8.RELEASE/spring-jcl-5.0.8.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-aop/5.0.8.RELEASE/spring-aop-5.0.8.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-beans/5.1.0.RELEASE/spring-beans-5.1.0.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.0.4.RELEASE/spring-boot-autoconfigure-2.0.4.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.0.4.RELEASE/spring-boot-starter-logging-2.0.4.RELEASE.jar:/Users/zlatkoc/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:/Users/zlatkoc/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/zlatkoc/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/zlatkoc/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.10.0/log4j-to-slf4j-2.10.0.jar:/Users/zlatkoc/.m2/repository/org/apache/logging/log4j/log4j-api/2.10.0/log4j-api-2.10.0.jar:/Users/zlatkoc/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/Users/zlatkoc/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/Users/zlatkoc/.m2/repository/com/fasterxml/jackson/module/jackson-module-kotlin/2.9.6/jackson-module-kotlin-2.9.6.jar:/Users/zlatkoc/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.6/jackson-databind-2.9.6.jar:/Users/zlatkoc/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.9.6/jackson-core-2.9.6.jar:/Users/zlatkoc/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.9.0/jackson-annotations-2.9.0.jar:/Users/zlatkoc/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.2.70/kotlin-stdlib-common-1.2.70.jar:/Users/zlatkoc/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.2.70/kotlin-stdlib-jdk8-1.2.70.jar:/Users/zlatkoc/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.2.70/kotlin-stdlib-jdk7-1.2.70.jar:/Users/zlatkoc/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.2.70/kotlin-stdlib-1.2.70.jar:/Users/zlatkoc/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/Users/zlatkoc/.m2/repository/org/jetbrains/kotlin/kotlin-reflect/1.2.70/kotlin-reflect-1.2.70.jar:/Users/zlatkoc/.m2/repository/commons-io/commons-io/2.6/commons-io-2.6.jar:/Users/zlatkoc/.m2/repository/org/springframework/spring-web/5.1.0.RELEASE/spring-web-5.1.0.RELEASE.jar:/Users/zlatkoc/.m2/repository/com/madgag/spongycastle/core/1.51.0.0/core-1.51.0.0.jar:/Users/zlatkoc/.m2/repository/com/google/protobuf/protobuf-java/2.6.1/protobuf-java-2.6.1.jar:/Users/zlatkoc/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar:/Users/zlatkoc/.m2/repository/com/google/code/findbugs/jsr305/2.0.1/jsr305-2.0.1.jar:/Users/zlatkoc/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/Users/zlatkoc/.m2/repository/com/lambdaworks/scrypt/1.4.0/scrypt-1.4.0.jar:/Users/zlatkoc/.m2/repository/org/bitcoinj/orchid/1.2.1/orchid-1.2.1.jar:/Users/zlatkoc/.m2/repository/com/squareup/okhttp/okhttp/2.7.2/okhttp-2.7.2.jar:/Users/zlatkoc/.m2/repository/com/squareup/okio/okio/1.6.0/okio-1.6.0.jar
Welcome to Kotlin version 1.2.71 (JRE 1.8.0_162-b12)
Type :help for help, :quit for quit
>>> import com.myproject.somepackage.SomeThing
error: unresolved reference: myproject
import com.myproject.somepackage.SomeThing
^
>>>
When I have just following in my init.kts:
//KOTLIN_OPTS -cp build/libs/myproject.jar
I can import classes from my local code:
$ kscript --interactive init.kts
[kscript] Creating REPL from init.kts
Welcome to Kotlin version 1.2.71 (JRE 1.8.0_162-b12)
Type :help for help, :quit for quit
>>> import com.myproject.somepackage.SomeThing
>>>
Activity
holgerbrandl commentedon Sep 28, 2018
I wonder why we don't the see warning when executing the script with
kscript init.kts? There's clearly the same duplication happening there.Anyway, I see your point and agree,.
We could address it properly by fixing #127, but this seems a bit too much given the beauty of your workaround.
To fix it as you suggested, we would need to parse the the aggregated
KOTLIN_OPTS, pull out (and remove) all classpath settings, and finally append them to the `classpath variable in https://github.com/holgerbrandl/kscript/blob/4bd118b881b4d97257562ea3d3045713107fdc44/src/main/kotlin/kscript/app/Kscript.kt#L146Before doing this we should ping the kotlin team on https://youtrack.jetbrains.net/oauth?state=%2Fissues%2FKT about whether multiple cp arguments should be legit or not, and why the repl invokation behavior differs from the application-invocation behavior. In java multiple
cparguments seem possible, see https://stackoverflow.com/questions/45291354/specifying-multiple-cp-or-classpath-entries-on-java-command-line . Could you do so, and potentially even provide the fix from above as PR? :-)DALDEI commentedon Apr 19, 2019
This is my #1 ... #100 use case for kscript and I cant get it to work.
Case: developing a library /app and want to run a .kts script using the current built code directory tree.
Ive tried publishing to custom maven repo (gradle resolves fine but MavenRepository does not), adding a classpath doesnt do it (see related issue)
DALDEI commentedon May 10, 2019
I took a stab at fixing this -- came close but no cigar -- but close.
My 'hack' of an idea, which is still viable but needs to be tweaked, is to work around the 'feature' of kotlin and kotlinc in a crude but effective way. I attempted this in the .kt code but it failed due to the mixture annotation and command line parsing and the early conversion of argument lists to strings making it difficult --- its not trivial to 'undo' concatenating shell arguments into seperate args short of running the shell. ('quoting is hard' Unquoting even harder). But here's trick.
Just prior to calling kotlin and kotlinc with the full command line, scan for and modify all "-cp" and "-classpath" options replacing them with a single one. I tested this crudely with a shell script and may try a better version. The concept should work and can be done without subprocess creation in shell.
How to invoke the code is an option -- the easiest would be to replace occurances of "kotlin" and "kotlinc" commands with private scripts like 'kscript-kotlin" -- another would be to modify the path to point to a local version of kotlinc/kotlin. Part of the work can be done in the current kscript -- but not all as there is subprocess callouts to "kotlinc" that need adjusting.
Basic shell pseudocode -- could be more concise and doesnt cover windows etc .. ( my other kotlin fix did, but didnt handle re-evalating strings back to individual args correctly )
Another option is to do a hacky regex just prior to calling println or kotlinc in the .kt code
that does the same -- extract all "-cpclasspath" and merge them -- but thats still problematic due to issues with spaces in paths etc which is hard to do with regex.
BETTER option is to catch all generation of classpaths 'upstream' and keep them seperate from the command line string, defering generation of the "-cp" options until the end.
holgerbrandl commentedon May 14, 2019
Thanks for the suggestion. In general, I think we should stay away from shell as much as possible to ease cross-platform portability.
holgerbrandl commentedon Jun 21, 2019
Closed because of inactivity