Javalin Migration from 3 to 4 - kotlin

We are migrating the Javalin from 3 to 4 in our current kotlin project. the dynamicGzip has been deprecated and replaced with compression strategy.
The pom.xml part will look like below.
<properties>
<javalin.version>4.1.1</javalin.version>
<jackson.version>2.13.0</jackson.version>
</properties>
The code part of kotlin is as follows
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.*
import io.javalin.http.BadRequestResponse
import io.javalin.http.NotFoundResponse
import io.javalin.http.staticfiles.Location
import io.javalin.plugin.json.JavalinJackson
import io.javalin.core.compression.*
val app = Javalin.create { config ->
config.defaultContentType = "application/json"
config.enableWebjars()
config.addStaticFiles("", Location.CLASSPATH)
config.enableCorsForAllgOrigins()
//it.dynamicGzip = true // deprecated method which was used in 3.12.0
config.compressionStrategy(Gzip(6))
}
We are using the migrating document from this link
https://javalin.io/migration-guide-javalin-3-to-4
When we try to build the project in intelij Idea with this change, ended with the below error.
D:\app\src\main\kotlin\app\app.kt:78:40
Kotlin: Unresolved reference: Gzip
What is that we are missing here?
Also it will be helpfull if config.addStaticFiles syntax is also added wrt javalin 4

Compression
The compressionStrategy method of the JavalinConfig class takes two parameters:
void compressionStrategy(Brotli brotli, Gzip gzip)
See the JavaDoc here.
The related classes are found in Javalin here:
import io.javalin.core.compression.Brotli;
import io.javalin.core.compression.Gzip;
So, you can do something like this in your set-up (my example is Java not Kotlin):
// my Java example:
config.compressionStrategy(new Brotli(6), new Gzip(6));
Static Files
You can use something like this (again, a Java example not Kotlin):
// my Java example:
config.addStaticFiles("/public", Location.CLASSPATH);
In this case, because I want my files to be on the runtime classpath, I have also created a public directory in my application's resources directory. Your specific implementation may differ.
You can also use Location.EXTERNAL if you prefer, to place the files somewhere else in your filesystem (outside the application).
Note also there is a small typo in config.enableCorsForAllgOrigins(). It should be:
config.enableCorsForAllOrigins()

Related

Python architecture, correct way to pass configurable initialization object to project modules

I have a big architecture question about how to pass set of configurable / replaceable objects to modules of my project?
For example the set may be a bot, logger, database, etc.
Currently I'm just importing they, it make a big problem when you want to replace them during a tests.
Lets' say import app.bot will hard to test and patch
I had tried a multiple solutions but failed with them:
Option 1:
Create some base class with which will accepts set of such objects (db, bot, etc).
Every logic class (who need this set) will inherit this class.
AFAIK the similar approach there in SqlAlchemy ORM.
So the code will looks like:
app.config.py:
Class Config:
db: DB
...
tests.py:
import app.config
Config.db = Mock()
create_app.py:
import app.config
def create_app(db):
app.config.Config.db = db
logic.py
import app.config
User(app.config.Config):
def handle_text(text):
self.db.save_text(text=text)
...
The problem with this case is that most likely you can't importing as from app.config import Config
because it will lead to wrong behavior and this is implicit restriction.
Option 2
Pass this set in __init__ arguments to every instance.
(It's ma be a problem if app has many classes, > 20 like in my app).
User:
def __init__(..., config: ProductionConfig):
...
Option 3
In many backend frameworks (flask for example) there are context object.
Well we can inject our config into this context during initialization.
usage.py:
my_handler(update, context):
context.user.handle_text(text=update.text, db=context.db)
The problem with this approach is that every time we need to pass context to access a database in our logic.
Option 4
Create config by condition and import it directly.
This solution may be bad because conditions increases code complexity.
I'm following rule "namespace preferable over conditions".
app.config.py:
db = get_test_db() if DEBUG else get_production_db()
bot = Mock() if DEBUG else get_production_bot()
P.S. this question isn't "opinion based" because in some point the wrong solutions will leads to bad design and bugs therefore.

ACE editor - allow custom modes and themes in Angular/TypeScript

Introduction:
I've an Angular application where custom SQL statements can be written by using the ACE editor (https://ace.c9.io/). Even though there are modes and themes for SQL, I wanted to create a custom mode and a custom theme for my requirements.
Setup:
I followed this tutorial: https://blog.shhdharmen.me/how-to-setup-ace-editor-in-angular
ng new ace-app (Angular 13.3.2)
npm install ace-builds (ACE-Builds 1.4.14)
component.ts
import * as ace from 'ace-builds';
...
public aceEditor: ace.Ace.Editor;
#ViewChild('editor') private editor!: ElementRef<HTMLElement>;
...
ngAfterViewInit(): void {
// I don't understand why we don't set the "basePath" to our installed package
ace.config.set('basePath', 'https://unpkg.com/ace-builds#1.4.12/src-noconflict');
this.aceEditor = ace.edit(this.editor.nativeElement);
if (this.aceEditor) {
this.aceEditor.setOptions({
mode: 'ace/mode/sql',
theme: 'ace/theme/sqlserver',
});
}
component.html
<div #editor></div>
Result:
The editor is working, but now I need to somehow add a custom mode and theme.
Problems and Questions:
Is it correct to set the basePath to an external URL if I've the package already installed (obsolete due to Edit 1)?
How and where would I add the custom mode.js and theme.js?
How can I direct ace to the custom mode.js and theme.js?
Edit 1:
I managed to get rid of this line of code:
ace.config.set('basePath', 'https://unpkg.com/ace-builds#1.4.12/src-noconflict');
by directly importing the theme and mode with:
import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';
the rest of the code did not have to be changed.
After looking through several projects and issues, I figured out that the best way to implement custom themes and modes for the ACE editor is to copy existing ones from ./node-modules/ace-builds/src-conflict and paste them to ./src/assets/ace.
Example:
Copy an existing mode (and optionally the theme) that represents your required syntax highlighting the most, in my case it was mode-sql.js. I copied the files to ./src/assets/ace and changed the import in my component.ts from:
import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';
To:
import '../../../../assets/ace/mode-sql.js';
import '../../../../assets/ace/theme-sqlserver.js';
Everything else was kept exactly as described in the initial question. From there you can start to change the name of mode and theme, update the rules as well as the styling according to your requirements.

How to add javascript js files into qmldir with qt_add_qml_module

I am creating a Qt6 QML module with qt_add_qml_module.
qt_add_qml_module(SQUtils_Logger_Qml
URI SQUtilsLogger.Qml
VERSION 1.0
SOURCES
LoggerQml.cpp
QML_FILES
Log.js
Logm.mjs
LoggerQml.qml
)
But the generated qmldir contains only the information about the qml file: the js and mjs files are missing.
module SQUtils.Logger.Qml
linktarget SQUtils_Logger_Qmlplugin
optional plugin SQUtils_Logger_Qmlplugin
classname SQUtils_Logger_QmlPlugin
typeinfo SQUtils_Logger_Qml.qmltypes
prefer :/SQUtils/Logger/Qml/
LoggerQml 1.0 LoggerQml.qml
It is a problem because when I run ninja all_qmllint, the compiler/linter complains that Log is not defined:
// View.qml
import SQUtils_Logger_Qml
//import "qrc:/SQUtils/Logger/Qml/Log.js" as Log
ApplicationWindow {
Component.onCompleted: {
Log.debug("QML main application complete")
}
}
Warning: View.qml:120:13: Unqualified access
Log.debug("QML main application complete)
If I append Log 1.0 Log.js to the qmldir file, then the linting works.
What I am doing wrong? Is this a bug? The qt documentation for qt_add_qml_module quotes:
QML_FILES lists the .qml, .js and .mjs files for the module. [...]
The files will also be used to populate type information in the generated qmldir file.
Thank you for your help!
Note: I can manage to run my code by uncommenting import "qrc:/SQUtils/Logger/Qml/Log.js" as Log, but the lint still does not work.
It was indeed a Qt bug, corrected two days ago. It will be corrected in versions greater than 6.2.2:
https://bugreports.qt.io/browse/QTBUG-100326

Kotlin Script Engine throws "unresolved reference", even if the package and class is valid

When using Kotlin's Script Engine, trying to import packages or use any class throws an "unresolved reference"
javax.script.ScriptException: error: unresolved reference: mrpowergamerbr
fun loritta(context: com.mrpowergamerbr.loritta.commands.CommandContext) {
^
This doesn't happen when running the class within IntelliJ IDEA, however it does happen when running the class on production.
While this YouTrack issue is related to fat JARs, this also can happen if you aren't using fat JARs (loading all the libraries via the startup classpath option or the Class-Path manifest option)
To fix this, or you can all your dependencies on your startup script like this:
-Dkotlin.script.classpath=jar1:jar2:jar3:jar4
Example:
java -Dkotlin.script.classpath=libs/dependency1.jar:libs/dependency2.jar:yourjar.jar -jar yourjar.jar
Or, if you prefer, set the property via code, using your Class-Path manifest option.
val path = this::class.java.protectionDomain.codeSource.location.path
val jar = JarFile(path)
val mf = jar.manifest
val mattr = mf.mainAttributes
// Yes, you SHOULD USE Attributes.Name.CLASS_PATH! Don't try using "Class-Path", it won't work!
val manifestClassPath = mattr[Attributes.Name.CLASS_PATH] as String
// The format within the Class-Path attribute is different than the one expected by the property, so let's fix it!
// By the way, don't forget to append your original JAR at the end of the string!
val propClassPath = manifestClassPath.replace(" ", ":") + ":Loritta-0.0.1-SNAPSHOT.jar"
// Now we set it to our own classpath
System.setProperty("kotlin.script.classpath", propClassPath)
While I didn't test this yet, in another unrelated answer it seems you can also supply your own classpath if you initialize the KotlinJsr223JvmLocalScriptEngine object yourself (as seen here)

Scala with spark - "javax.servlet.ServletRegistration"'s signer information does not match signer information of other classes in the same package

I have simple scala application with spark dependencies. I am just trying to create spark context using the follwing code.
def main(args: Array[String]) {
var sparkConfig : SparkConf = new SparkConf() ;
sparkConfig.setAppName("ProxySQL").setMaster("local");
var sc = new SparkContext(sparkConfig)
}
When i try to run this code inside main - it throws security execption at new SparkContext(sparkConfig) with the following message .
Exception in thread "main" java.lang.SecurityException: class "javax.servlet.ServletRegistration"'s signer information does not match signer information of other classes in the same package .
At problem tab of Eclipse, it shows one warning
Description Path Resource Location Type
More than one scala library found in the build path (D:/workspaces/scala/scalaEclipse/eclipse/plugins/org.scala-ide.scala210.jars_4.0.0.201503031935/target/jars/scala-library.jar, C:/Users/prems.bist/.m2/repository/org/scala-lang/scala-library/2.10.4/scala-library-2.10.4.jar).This is not an optimal configuration, try to limit to one Scala library in the build path. SQLWrapper Unknown Scala Classpath Problem
I have scala installation of 2.10.4 at windows machine.
Scala compiler version set at eclipse is 2.10.5 . What is causing this security exception? Is this the incompatiblity version issues or what exaclty else? How would i solve it?
The problem was more or less related with conflicting dependencies.
The following task resolve my issue.
Go to Project
Build Path -> Order and Export tab -> Change the order of
javax.servlet jar
either to bottom or top.
This Resolved the problem.
Well,as I follow the suggestion:Go to Project Build Path -> Order and Export tab -> Change the order of javax.servlet jar either to bottom or top.
I find my buidpath libiaries was changed and it seems mussy(too many small libs),maybe this was caused by maven.
So I try to remove all of them and reimport the libs and chose Project -> Maven ->Update Project !
Now ,it goes well.
The name of your object with the main method shoul be the same as the setAppName("ProxySQL"), also you can exttend it with app and do not use main method, but this is only if you want I find it easy.
package spark.sample
import org.apache.spark.{ SparkContext, SparkConf }
/**
* Created by anquegi on 18/05/15.
*/
object ProxySQL {
def main(args: Array[String]) {
var sparkConfig: SparkConf = new SparkConf();
sparkConfig.setAppName("ProxySQL").setMaster("local");
var sc = new SparkContext(sparkConfig)
}
}
I normally use and object like for using Spark
package spark.sample
import org.apache.spark.{ SparkContext, SparkConf }
/**
* Created by anquegi on 18/05/15.
*/
object ProxySQL extends App {
val sparkConfig: SparkConf = new SparkConf();
sparkConfig.setAppName("ProxySQL").setMaster("local[4]");
val sc = new SparkContext(sparkConfig)
}
I prefer to use val instead of var
You can also setMaster with .setMaster("local[4]"), and not work only with one
It means you did not exclude the Servlet APIs from some dependency in your app, and one of them is bringing it in every time. Look at the dependency tree and exclude whatever brings in javax.servlet.
It should be already available in Spark, and the particular javax.servlet JAR from Oracle has signing info that you have to strip out, or simply exclude the whole thing.
some of the libraries were mention here