Main method works for java, but not scala - java

I have a module in intellij, where I can create main methods in java which run perfectly, but when I create them in scala and attempt to run them, I get the following:
Error: Could not find or load main class xxx
My project relies on both java and scala classes. What do I need to do to allow scala main classes to run?
EDIT:
As requested, here's an excerpt of the main class I'm trying to run with scala. I know there's nothing wrong with the code because it works when I initialize the code in intellij as a scala project. The problem here is that I started with a blank project, so I don't know what magic intellij did behind the scenes to make the scala main classes run properly.
object WebProxyServer extends Logging {
def main(args: Array[String]): Unit = {
// implementation
}
}
class WebProxyServer() {
}

The easiest way to run Scala code is to create an object that extends App, like this:
object Main extends App {
println("Hello World")
}
Scala will execute all the code in the object when it is created. (The arguments are available in the args member of App)
To run this from IntelliJ, select "Run->Edit Configurations", then click "+" and select "Application" and fill in the dialog. The drop-down for the "Main Class" parameter should include all objects that extend App, so pick the class you want to run. Once this is done, your Main should appear on the "Run" menu.
You can have multiple classes that extend App and multiple items in the Run menu. I use this to debug specific parts of the code from the IDE without having the run the main program.
You can also create an object with a main method like this:
object Main {
def main(args: Array[String]): Unit = {
println("Hello World")
}
}
Once this is built you can add Main as a "Main Class" in IntelliJ as described above. All objects with a main method will also appear in the "Main Class" drop-down.
Both approaches are acceptable, but don't combine the two. That is, don't inherit from App and then override the main method in App.

To add Scala code to an existing Java module in Intellij, right click on the module name (usually the top level folder in the project view), and click "Add Framework Support", then check Scala in your list of options.
To add Scala code to a new module in an Intellij project, goto File -> New Module, and choose Scala from the list of options.
If your directory structure looks like this:
src
|
|-main
|
|-java
| |-....java packages
|
|-scala
|-....scala packages
Then don't forget to right click your scala directory in the project view and choose Mark Directory As -> Sources Root

first try check the SDK configuration to your IDE and if this cause you error.
object WebProxyServer {
def main(args: Array[String]): Unit = {}
}
then try extends App and override your main(args: Array[String]) if needed

Make sure you're adding the main method to objects, not classes. The main method needs to be static. You can add a companion object, which is just an object with the same name as the class, to contain the main method if you want to add a main method to an existing class.
class MyApp {
// bad main method; will not run
def main(args: Array[String]): Unit = println("hello world")
}
// companion object to MyApp class
object MyApp {
// good main method; will run fine
def main(args: Array[String]): Unit = println("hello world")
}

Related

Use a groovy script from another groovy script

I want to use a 'Util' groovy script inside another groovy script. I don't want to load 'Util' class inside my 'main' groovy script every time. So using evaluate or GroovyShell don't fit my case.
My java application fetches the 'main' groovy script body from a database, parse it and call test() method from 'main' script every time.
java code :
GroovyShell groovyShell = new GroovyShell();
Script parsedScript = groovyShell.parse(scriptBody);
ResultPojo result = (ResultPojo) parsedScript.invokeMethod("test", null);
'main' script
public int test(){
// this will not work at the moment
int result = GroovyUtils.sum();
return result;
}
A 'Util' class will be located in the database too. 'Util' classes will be somehow loaded on application startup and they will be reloaded every X minutes.
class GroovyUtils{
static int sum() {
return 2+1;
}
}
Like i said i don't want to 'parse' the GroovyUtils class inside 'main' script because this is time costly.
Ideally i want to import GroovyUtils script when i need it.
import groovy.GroovyUtils;
public int test(){
int result = GroovyUtils.sum();
return result;
}
But in order to import the script, the script need to be saved in the same folder that the java application runs. The java application is deployed on a remote application server in .war format.
Can i somehow load GroovyUtils dynamically to CLASSPATH without saving it, so i can import it from my 'main' script?
Any suggestions? My main concerns is speed and reloadability.
if you'd like to create a delivery process through the database you can do it by extending GroovyClassLoader and implementing public Class loadClass(name, lookupScriptFiles, preferClassOverScript, resolve) method that will search classes in some table in a database.
Let me simplify your goal and exclude database.
There is a standard behavior of classloaders: search and load classes among the classpath
The GroovyClassLoader allows to add new paths to a classpath at runtime, so it will search additionally classes in specified folder or jar file.
classloader keeps parsed classes in memory and groovy classloader provides protected method to remove class definition by name: removeClassCacheEntry(java.lang.String)
and finally example:
/myprj/classes/util/MyClass.groovy
package util
class MyClass{
def echo(msg){ println msg }
}
code to run main script
//create shell and init classloader just once
GroovyShell gs = new GroovyShell()
gs.getClassLoader().addClasspath("/myprj/classes/")
//forces classloader to recompile on file change
//this is alternative to removeClassCacheEntry
//but in some specific cases this reload will not work
gs.getClassLoader().setShouldRecompile​(true)
Script script = gs.parse('''
import util.MyClass
new MyClass().echo("hello world")
''')
script.run() // prints 'hello world'
//removeClassCacheEntry is alternative to setShouldRecompile​
//you can use it to remove compiled class from this classloader
println gs.getClassLoader().getLoadedClasses() // outputs util.MyClass, and Script1
gs.getClassLoader().removeClassCacheEntry("util.MyClass")
println gs.getClassLoader().getLoadedClasses() // outputs Script1
returning to the database: you could have a daemon thread that scans database for groovy code changes and exports modified sources into a folder that was defined as additional classpath and triggers removeClassCacheEntry for the classloader. So, next access to removed class will force to parse it by GroovyClassLoader.
NOTE: by using dynamic class loading you could have situation when two versions of same class present in memory and they will not be comparible and assignable to each other. So, you could have the error like: could not assign MyClass to MyClass

How to add unit tests to Java project in intellij IDEA?

I want to create simple java project with JUnit, so for example I'm want to write an algorithm like merge sort or some Java class and create test class so I can make unit test for that class.
I've create the project with:
File -> New -> Project -> java -> next and setup the project name and
location
and I want to make the unit test for the class the I've created, and I've tried the following solotions :
solution 1 from IntelliJ IDEA dosc using the light bulb to create the test class
solution 2 using shortcut [ctrl + shift + t]
But I always endup with import static org.junit.Assert.*; cannot resolve symbol 'junit', I tried different unit test library end up the same way.
How to resolve this problem so I can make unit test class in this simple Java project?
You can use Gradle or Maven (my personal preference these days).
But the easiest way is to add the JUnit JAR to your project, write some tests, and execute them in IntelliJ.
Go to JUnit and download version 4.12 of the JAR. Put it in a folder /test-lib in your IntelliJ project.
Create a folder /src and add a package /model and a Java class Foo to it (I'll write you one).
Mark /src as a source root.
Create a folder /test and add a package /model and a Java class FooTest to it (I'll write that, too).
Mark /test as a test source root.
Right click on /test and tell IntelliJ to "Run All Tests".
IntelliJ will run all the tests and present the results in the Run window.
Here's the model class:
package model;
public class Foo {
private String value;
public Foo(String v) { this.value = v; }
public String toString() { return this.value; }
}
Here's the test class:
package model;
public class FooTest {
#Test
public void testToString() {
String expected = "Test";
Foo foo = new Foo(expected);
Assert.assertEquals(expected, foo.toString());
}
}
I'm not sure this is the best solutions but I manage to build the unit test use gradle and maven. like this :
create Java project :
File -> New -> Project -> Gradle -> choose only java-> fill the
groupId and ArtifactId-> choose use default gradle wrapper -> enter
project name and location ->finish
and from the root of the project
right click -> Add Framework Support -> choose maven.
from there I can create the class that I want and make the unit test using the solutions from the question [ctrl + shift +t] .

How to initialize members of App without running the App (main)?

I have a class MyClass, which extends App. The thing is that, inside MyClass, there is a variable myValue that I need to initialize, without actually running the app. The reason for this is because I want to run unit tests of the methods of MyClass in a non-interactive way.
class MyClass extends App {
val myValue = "A value that I need to run the unit tests"
def myMethod: Unit = "A method that needs to be unit-tested and uses " + myValue
/* ... main (interactive) code that is not supposed to run in the unit test... */
}
So, the question is: How can I initialize members of App without running the app (main)?
From scaladocs of App trait:
==Caveats==
It should be noted that this trait is implemented using the DelayedInit functionality, which means
that fields of the object will not have been initialized before
the main method has been executed.
It seems that your only option is to declare main method def main(args: Array[String]): Unit = ... as you would do in Java instead of extending App.

How to link feature and step definition in cucumber

I'm new to Cucumber java and had this problem in initial stages:
I'm not using MAVEN project for some reason. I just created a simple java project in eclipse.
I have my features under "src/dummy/pkg/features", and my implementation "StepDef.java" is under "src/dummy/pkg/features/implementation"
I have written step definitions for Given, When, and Then, but when I run my features file, it is unable to recognize the implementation. How do I link the features with step definitions?
create a class YourClass and it would look something like the below and run it as JUnit test.
#RunWith(Cucumber.class)
#CucumberOptions( monochrome = true,
features = "src/dummy/pkg/features/",
format = { "pretty","html: cucumber-html-reports",
"json: cucumber-html-reports/cucumber.json" },
glue = "your_step_definition_location_package" )
public class YourClass {
//Run this from Maven or as JUnit
}
When you run your Runner class then it will scan all the feature file mentioned within features options and load the them afterward all step definition within package started by text mentioned within glue options will get loaded.
For e.g.
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = { "pretty","json:target/cucumberreports.json" },
glue = "stepDefinition",
features = "src/test/resources/TestCases/",
tags={"#onlythis"},
dryRun=false
)
public class RunTest {
}
Here all the feature file present within
src/test/resources/TestCases/
will get loaded
then all the stepdef within or it's subdirectory will get loaded
stepDefinition
and whenever your step from feature get run then cucumber will look for function corresponding to step's regex and function will run.
for e.g.
whenever step When User enters email id in src/test/resources/TestCases/Login.feature will run then cucumber will find its corresponding function in all stepdef classes
Login.feature
#LoginValidation
Feature: To smoke test functionalities of app
#Browser #ValidLogin
Scenario: Verify scenario in case of successful login
When User enters email id
And User enters password
Then User clicks on sign in button and able to sign in
And moment it will reach class in subdirectory of stepDefinition i.e. in
stepDefinition.ui.home.LoginPageStepDef.java cucumber will find function with #When("^User enters email id$") and will execute this function.
LoginPageStepDef.java
public class LoginPageStepDef {
LoginPage loginPage = new LoginPage(AttachHooks.driver);
private static Logger LOGGER = Logger.getLogger(LoginPageStepDef.class);
#When("^User enters email id$")
public void user_enters_email_id() throws Throwable {
//LoginPage.obj = loginPage;
loginPage.enterEmailId(ConfigManager.getProperty("UserName"));
}
}
You have to convert your project to Cucumber project. Right-click on your project from the Project Explorer > Configure > Convert as Cucumber Project.
Create a runner class something like this and you should be able to execute.
There is also no need to write step definitions manually, just create a feature file and run it, it will create a snippet of the step definition which can be used to create a step definition class:
A class file called Runnerclass is required to run the cucumber:
#RunWith(Cucumber.class)
#CucumberOptions(plugin={"pretty","html:format"},
features = "Features/name.feature",glue={"path where step definitions exist"})
public class RunnerClass {
}

The scala plugin for IDEA 12.x not working as expected with akka

I am trying to use akka with maven and scala and I have added the akka actor jars to my pom.
Now in IDEA I go ahead and type this up,
class HelloWorld extends Actor {
}
At this point it correctly highlights HelloWorld as in error. I try to fix the errors and it correctly says that I have unimplemented methods (receive). I say go ahead and add the method and it does nothing.
I am using
IDEA 12.1.6
Scala plugin 0.22.302
Mac OSX 10.9.2
Note that if I created a trait myself
trait MyTrait {
def foo : Void
}
and tried to implement it like so
class MyImpl extends MyTrait {
}
Then I am correctly prompted for methods to be added and it does add the methods when I say go ahead.

Categories