I have an Java application on Google App Engine.
I would like to change the configurations of appengine-web.xml without compile the package again, bacause I have to pass the same final package (war) for each environment. (DEV, HOM, PRD).
My problem is, I would like to change the instance-classe in some environments because on HOM I can use a less power instance than PRD.
There is a way to set this values in with variables or another way to do it?
I could do it with maven and replace the file, but I want to keep the same final package for each environment.
Related
I'm working with Collibra java APIs in eclipse (which leverages the flowable workflow engine).
There are pre-instantiated classes in the engine, which eclipse (obviously) does not know about.
Is it possible to configure eclipse to automatically instantiate classes in order to provide autocomplete support?
i.e. to configure eclipse to perform the following code automatically?
import com.company.module.package.MyClass
MyClass myClass = new MyClass()
This way, the myClass variable would always be available for autocomplete without having to declare it every single time.
Edit: Even better, is there any way to configure eclipse to include variables loaded into the execution environment of flowable?
For example we would load one variable in one file, would the eclipse autocomplete be able to have access to that variable in another file?
In flowable, the syntax is:
execution.setVariable("myVariable", myVariable)
Thanks to emilles for putting me on the right track.
Here's the solution. This works when the Groovy developer tools plugin is installed.
open a new groovy script and type the name of the variable you want to add to content assist
press ctrl + 1 to bring the quick assist menu and press "Add inferencing suggestion"
Fill the information as described below
This will create an entry in a file located under your project root as .groovy/suggestions.xdsl
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<projectSuggestions>
<declaringtype type="groovy.lang.Script">
<property isActive="true" isStatic="false" name="execution" type="org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl">
<doc/>
</property>
</declaringtype>
</projectSuggestions>
From then on, the "execution" variable will be automatically recognized by eclipse as an instance of org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl
I need to tune the JVM memory by help of Gradle. I've writen settings in the gradle.properties file:
org.gradle.jvmargs=-XX:MaxMetaspaceSize=60M
but it didn't work. Then I've done it manually in an IDEA (Run>Edit Configurations...) and wrote the settings for the needed class (in VM options: field) and it works. Can we do the same by help of Gradle?
I've tried to do:
org.gradle.jvmargs=-XX:MaxMetaspaceSize=60M test1.Test
but I got the error:
Error: Could not find or load main class test1.Test
When you run your application via IDEa, it runs the application using java ... command and gradle is not involed at all, so whatever you put in build.gradle doesn't matter.
If you want to run your app via gradle, consider using application plugin, which allows you to set jvm args. If you use Spring Boot use can use bootRun task and specify params in jvmArgs property.
I am using Hot Code Replace feature when Tomcat is running from eclipse and it works great.
But, how can I do this manually when Tomcat is running outside eclipse?
After some searching, I have found that I need to use an agent like HotswapAgent. But, they are using this agent with modified JDK called DCEVM. I don't want to use modified JDK. I want to achieve the same thing with OpenJDK.
I know that modification will be limited to method body only but, that's not a problem for me. How can I achieve the exact same thing eclipse is doing for Hot Code Replace for an externally running Tomcat without using IDE?
Edit : Eclipse example is just to clarify what I want to achieve. I do not want to use eclipse at all. I just want to do Hot Code Replace in an application running in Tomcat.
Yes, it's possible to perform Hot Code Replace in a running JVM. This involves several steps.
Prepare (compile) the new version of classes you want to replace. Let's say, you want to replace org.pkg.MyClass, and the new version of this class is located at /new/path/org/pkg/MyClass.class
Create a Java Agent that uses Instrumentation API to redefine the given class. Here is how the simplest agent may look like:
import java.lang.instrument.*;
import java.nio.file.*;
public class HotCodeReplace {
public static void agentmain(String args, Instrumentation instr) throws Exception {
Class oldClass = Class.forName("org.pkg.MyClass");
Path newFile = Paths.get("/new/path/org/pkg/MyClass.class");
byte[] newData = Files.readAllBytes(newFile);
instr.redefineClasses(new ClassDefinition(oldClass, newData));
}
}
Compile the above agent and pack it into .jar with the following MANIFEST.MF
Agent-Class: HotCodeReplace
Can-Redefine-Classes: true
The command to create HotCodeReplace.jar:
jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
Load the agent .jar into the target JVM. This can be done with Attach API or simply with jattach utility:
jattach <pid> load instrument false /path/to/HotCodeReplace.jar
More about Java agents ยป
I'm building a Java desktop application, using JavaFX, Gradle, javafx-gradle-plugin. This application connects to a server that I also build. When I compile a release version, running gradle jfxNative, I want it to talk to the production server; but otherwise, I want it to talk to localhost.
What's the proper Java/Gradle way of handling this? Some sort of compilation profile?
You can use Gradle's source sets for this:
Sample build.gradle:
apply plugin: 'java'
sourceSets {
prod {
java {
srcDirs = ['src/main/java', 'src/prod/java']
}
}
dev {
java {
srcDirs = ['src/main/java', 'src/dev/java']
}
}
}
task devJar(type: Jar) {
from sourceSets.dev.output
manifest {
attributes("Main-Class": "MyPackage.MyClass")
}
}
task prodJar(type: Jar) {
from sourceSets.prod.output
manifest {
attributes("Main-Class": "MyPackage.MyClass")
}
}
Now you can create two configuration classes for your dev and prod versions:
src/dev/java/MyPackage/Configuration.java
src/prod/java/MyPackage/Configuration.java
All the common code will be in the main source set:
src/main/java/MyPackage/MyClass.java
MyClass can get some values from the configuration class (e.g. Configuration.getBaseUrl())
Running gradle devJar/ gradle prodJar builds one of the variants.
Note: you may need to extend jfxNative/jfxJar instead of Jar in your case.
The simplest solution: Have a configuration file containing such information.
You either compile it into the application as a java resource or place it next to the jar file so it can be easily looked up via the filesystem.
With gradle all you need to do is define two build tasks with different input properties and insert the values into your properties file with groovy templating.
application.properties in src/main/resources:
server.address=${serverAddress}
add to your build.gradle
task setProductionServerAddress {
processResources.expand([serverAddress: "https://app.example.com/v1"])
}
jfxJar.dependsOn(setProductionServerAddress)
jfxNative.dependsOn(setProductionServerAddress)
And then on the application:
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("/application.properties"));
if (properties.getProperty("server.address").equals("${serverAddress}")) {
setUrl("http://localhost:8080/v1");
} else {
setUrl(properties.getProperty("server.address"));
}
Have it check environment variables for names of configuration files. Nothing to do with gradle or build. The same program should run properly wherever it is deployed.
See, e.g., Properties for dev and production
The easiest approach is to define a system property which specifies where the file system location for your data is. The production appserver would define one value (using java -D in the startup script), and your dev app server would define another value. Your application source would consult the system property value (using System.getProperty()) to discover the appropriate location
Also, this makes sense.
Put the information you need in JNDI - that's what it is designed for.
Consider letting your application refuse to do anything if the information is not there.
Another reference: What is the best way to manage configuration data
EDIT: Well, what you're asking is logically not possible then, it seems to me. "It should connect to production, unless a specific someone wants to connect to development, but that feature should only be available to unknown persons" The start menu is only a shortcut for running the application, so you can install a "dev" shortcut with command line settings that are read as environment vars.
I would go with the one of the "12 factor app" concept which can be read here
One of its main concept is to use system environment variable which should determine whether you are working on a prod or dev or qa env etc.
each project/environment/machine should contain its relevant env property, which after then can be retrieved through the gradle process similar to maven profile plugin.
An example for how to detect:
`if (project.hasProperty('env') && project.getProperty('env') == 'prod') {
apply from: 'gradle/production.gradle'
} else {
apply from: 'gradle/development.gradle'
}`
more on this approach using gradle can be found: gradle profile
In my opinion and like others have suggested, this has little to do with the build and more to do with Run Time.
Therefore you could resort to checking for some kind of run time flag - a convenient and often used approach is to use System Properties.
On your Dev box, you could set an Environment variable - lets say FX _DESKTOP_APP_ENV = DEV or some such.
From your code you can look this up and decide the URL you want to use.
String env = System.getenv("FX _DESKTOP_APP_ENV");
String url = env == null ? "Production" : env;
On windows systems you can set up your system environment variables like so -- enter link description here
On *nix systems enter link description here
Hope this helps
You need to pick a configuration scheme (if JavaFX doesn't pick one for you).
I like https://github.com/typesafehub/config .
The config library will have instructions on how to make your "production" config differ from your "development" config.
See also JavaFX:Editable Configuration Files After Packaging
What's the proper Java/Gradle way of handling this? Some sort of compilation profile?
No, I would strongly recommend against compiling different code for production v.s. test. It will invalidate your testing. This should be handled in configuration, not in code. The conventional Java way of doing this is with configuration files (which can be compiled into the JAR as resources).
How to do this with Typesafe Config
I've had a bit of a look, and I am surprised not to find a good quality tutorial I can link you to here, sorry (I found a few rubbish ones). Perhaps this question will become a reference for others.
I would do something like this:
Create a "dev" and "prod" config files, along the lines of https://stackoverflow.com/a/33261928/8261
Arrange for your app to use the "dev" config file when running in your IDE and "prod" config file when running from a compiled JAR, as per Can you tell on runtime if you're running java from within a jar?
My guess as to why there aren't many tutorials for this is that all application or web Frameworks handle this for you.
Is there any possibility to get a map of environment variables that are used in Jenkins?
I am trying to develop my own plugin and need to access the variable BUILD_USER_ID, which is provided by the build user vars plugin.
There is a class called EnvVars, which inherits from TreeMap, but it is obviously empty, if you create an object of this.
EnvVars env = new EnvVars();
Where are these variables stored , so that I can get them and use them in my plugin?
I expect you mean build variables injected by Build User Vars Plugin into build.
If you are interested in reading static jobs configuration (from system groovy script for instance), use job.getBuildWrappersList().get(org.jenkinsci.plugins.builduser.BuildUser.class) to get user configured instance of BuildUser. In case of Build User Vars Plugin there is not much configuration to read, though.
If you would like to access actual variable values injected into the build process (from a BuildStep for instance), call build.getEnvironment(TaskListener) to get populated EnvVars instance with all variables. Note that these variables are not available outside of build context.