How to deploy a Ruby class in a Java web project - jar

I am trying to create an hybrid between a JRuby and a Java application, so that it may be possible to migrate single components at a time. What I am trying to do right now is really simple, here is the Ruby class:
require 'java'
java_package 'eu.netprophecy.test'
class RubyViewModel
java_signature 'String getGreeting()'
def getGreeting
puts "Hello, ZK, from Ruby!"
end
end
I want to be able to use this View Model from a ZK project:
<?page title="Hello, Ruby!" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="Hello Ruby!!" border="normal" width="200px" apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('eu.netprophecy.test.RubyViewModel')">
<label value="#load(vm.greeting)"/>
</window>
</zk>
I tried creating a jar with marbler, but it places the .class file with the java bytecode in a directory with the project name in front, messing with the expected package structure (in this case I get EJB/eu/netprophecy/test/RubyViewModel, which means I am unable to use the generated Java class in the Java code).
Does anyone know if this is at all possible, if there are better ways to do it,, or if I have to create manually the jar?

you need to generate a java class from your ruby class which is perfectly possible (even without pre-compilation) with become_java!, just make sure the ruby script gets executed before the view is rendered (or compiled I'm not sure what you're using).
class RubyViewModel
java_signature 'String getGreeting()'
def getGreeting
puts "Hello, ZK, from Ruby!"
end
end
require 'jruby/core_ext'
RubyViewModel.become_java! # returns a java.lang.Class
you might check the method is there (the java way) using :
RubyViewModel.java_class.getDeclaredMethods.map { |method| method.to_s }

Related

How to use PrimeNG with Angular in aspnetcore-spa template

You know, I spend more time just trying to get things set up to work with Angular than I do actually developing with Angular. There must be an easier way... :(
Currently, I am using the aspnetcore-spa template, creating a project with the command "dotnet new angular" - this is version 1.0.3, which adds Angular 4.1.2 to the npm dependencies. This works great to get a project running quickly. But now I want to add PrimeNG to take advantage of their form controls. I have been struggling with this all day, and would love it if anyone could provide some assistance.
Here is what I have done in my current effort (the latest of many, starting fresh each time):
1) Added to the package.json file: "primeng": "4.1.0-rc.2"
2) Added 'primeng/primeng' to the webpack.config.vendor.js file's vendor collection.
3) Added the following to my test module (which is in turn referenced in app.module.shared.ts so I can route to it via my RouterModule):
import { FileUploadModule } from 'primeng/components/fileupload/fileupload';
And in the html for the module, in an attempt to use the file uploader control, I have (from their site - https://www.primefaces.org/primeng/#/fileupload):
<p-fileUpload name="myfile[]" url="./upload.php"></p-fileUpload>
4) ran "webpack --config webpack.config.vendor.js" from a command prompt at the root of the project folder, which completed with no errors.
Then I hit F5 to run the project, and I got this error:
Exception: Call to Node module failed with error: Error: Template parse errors:
'p-fileUpload' is not a known element:
1. If 'p-fileUpload' is an Angular component, then verify that it is part of this module.
2. If 'p-fileUpload' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message. (" type="button" (click)="onclick()" class="ui-button-info" label="Click Me">Click Me</button>-->
So, in an effort to comply, I added a reference to the ngprime module to the app.module.shared.ts file, like this (I don't really know how I should reference the module...):
import { FileUploadModule } from 'primeng/primeng';
But got the same exact error.
What am I missing???
Any help would be most appreciated.
I finally have this working, using the asp-prerender-module to get server-side rendering, and not having to rely on the asp-ng2-prerender-module (see my last comment). The trick, I found, was to reference the FileUploaderModule in the app.module.shared.ts file like this:
import { FileUploadModule } from 'primeng/components/fileupload/fileupload';
rather than like this:
import { FileUploadModule } from 'primeng/primeng';
The reason this matters is that the latter method of referencing will load all other components as well (see explanation here: https://www.primefaces.org/primeng/#/setup), and SOME of the PrimeNG components can not be rendered on the server due to DOM-related references (things like "window", which do not exist on the server). See the discussion here for more on this: https://github.com/primefaces/primeng/issues/1341
This change, combined with the other steps listed in my answer and, of course, actually referencing the directive in app.module (thank you #pankaj !) made everything work correctly at last. Only took me about 7 hours to figure it out. :(

Seeing Websphere class instead of a class in one of my app's jars

I'm having what seems to be a classloader/jar issue. Websphere 7, JDK 6.
Talking to a webservice works fine when the code is running in a simple, standalone Java class.
((WSBindingProvider) docManClient).setOutboundHeaders(Headers.create(otAuthElement));
In the debugger, the docManClient object has this toString():
JAX-WS RI 2.1.4-b01-: Stub for http://innov15.ncr.pwgsc.gc.ca/innov15_cws/DocumentManagement.svc
The class path includes jaxws-rt-2.1.4.jar.
When the code is running inside Websphere, the cast fails.
((WSBindingProvider) docManClient).setOutboundHeaders(Headers.create(otAuthElement));
java.lang.ClassCastException: com.sun.proxy.$Proxy484 incompatible with com.sun.xml.ws.developer.WSBindingProvider
In the debugger, the docManClient object has this toString():
org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler#a460a46
This jar is in Websphere-land only, and is not part of my project's .ear file:
C:\dev_tools\server\IBM\WebSphere\AppServer\plugins\org.apache.axis2.jar
I attempted to change the app config, to prefer its own classes above those of Websphere.
I used the wsadim tool to change to PARENT_LAST, but this had no affect on the observed behaviour:
set dep [$AdminConfig getid /Deployment:my-ear/]
set depObject [$AdminConfig showAttribute $dep deployedObject]
set classldr [$AdminConfig showAttribute $depObject classloader]
$AdminConfig showall $classldr
$AdminConfig modify $classldr {{mode PARENT_LAST}}
$AdminConfig save
$AdminConfig showall $classldr
The app is an .ear which contains a single .war.
EDIT added later: I'm not clear on the relation between jax-ws-rt.jar and axis2.jar. The axis2.jar is not a drop-in replacement for jax-ws-rt.jar: when I switch to axis2.jar, the code no longer compiles.

spring boot/spring web app embedded version number

What are the strategies to embed a unique version number in a Spring application?
I've got an app using Spring Boot and Spring Web.
Its matured enough that I want to version it and see it displayed on screen at run time.
I believe what you are looking for is generating this version number during build time (Usually by build tools like Ant, Maven or Gradle) as part of their build task chain.
I believe a quite common approach is to either put the version number into the Manifest.mf of the produced JAR and then read it, or create a file that is part of the produced JAR that can be read by your application.
Another solution would be just using Spring Boot's banner customization options described here: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-banner
However, this will only allow you to change spring-boot banner.
I also believe that Spring Boot exposes product version that is set in Manifest.MF of your application. To achieve this you will need to make sure Implementation-Version attribute of the manifest is set.
Custom solution for access anywhere in the code
Lets assume you would like to have a version.properties file in your src/main/resources that contains your version information. It will contain placeholders instead of actual values so that these placeholders can be expanded during build time.
version=${prodVersion}
build=${prodBuild}
timestamp=${buildTimestamp}
Now that you have a file like this you need to fill it with actual data. I use Gradle so there I would make sure that processResources task which is automatically running for builds is expanding resources. Something like this should do the trick in the build.gradle file for Git-based code:
import org.codehaus.groovy.runtime.*
import org.eclipse.jgit.api.*
def getGitBranchCommit() {
try {
def git = Git.open(project.file(project.getRootProject().getProjectDir()));
def repo = git.getRepository();
def id = repo.resolve(repo.getFullBranch());
return id.abbreviate(7).name()
} catch (IOException ex) {
return "UNKNOWN"
}
}
processResources {
filesMatching("**/version.properties") {
expand (
"prodVersion": version,
"prodBuild": getGitBranchCommit(),
"buildTimestamp": DateGroovyMethods.format(new Date(), 'yyyy-MM-dd HH:mm')
)
}
}
processResources.outputs.upToDateWhen{ false }
In the code about the following is happening:
We defined a function that can take a build number out of the VCS
(in this case Git). The commit hash is limited to 7 characters.
We configure the processResources task to process
version.properties file and fill it with our variables.
prodVersion is taken from Gradle project version. It's usually set
as version in gradle.properties file (part of the general build
setup).
As a last step we ensure that it's always updated (Gradle
has some mechanics to detect if files ened to be processed
Considering you are on SVN, you will need to have a getSvnBranchCommit() method instead. You could for instance use SVNKit or similar for this.
The last thing that is missing now is reading of the file for use in your application.
This could be achieved by simply reading a classpath resource and parsing it into java.util.Properties. You could take it one step further and for instance create accessor methods specifically for each field, e.g getVersion(), getBuild(), etc.
Hope this helps a bit (even though may not be 100% applicable straight off)
Maven can be used to track the version number, e.g.:
<!-- pom.xml -->
<version>2.0.3</version>
Spring Boot can refer to the version, and expose it via REST using Actuator:
# application.properties
endpoints.info.enabled=true
info.app.version=#project.version#
Then use Ajax to render the version in the browser, for example using Polymer iron-ajax:
<!-- about-page.html -->
<iron-ajax auto url="/info" last-response="{{info}}"></iron-ajax>
Application version is: [[info.app.version]]
This will then show in the browser as:
Application version is: 2.0.3
I'm sure you've probably figured something out since this is an older question, but here's what I just did and it looks good. (Getting it into the banner requires you to duplicate a lot).
I'd recommend switching to git (it's a great SVN client too), and then using this in your build.gradle:
// https://github.com/n0mer/gradle-git-properties
plugins {
id "com.gorylenko.gradle-git-properties" version "1.4.17"
}
// http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
springBoot {
buildInfo() // create META-INF/build-info.properties
}
bootRun.dependsOn = [assemble]
And this in your SpringBoot application:
#Resource
GitProperties props;
#Resource
BuildProperties props2;
Or this way to expose those properties into the standard spring environment:
#SpringBootApplication
#PropertySources({
#PropertySource("classpath:git.properties"),
#PropertySource("classpath:META-INF/build-info.properties")
})
public class MySpringBootApplication {
and then referencing the individual properties as needed.
#Value("${git.branch}")
String gitBranch;
#Value("${build.time}")
String buildTime;

Flex conditional compilation of MXML?

In Flex it is now possible to use the -define compiler option to do all sorts of cool stuff.
In my program, I am using the option such that some of my code is excluded by blocks like this:
CONFIG::FACEBOOK{
//Some code
}
And this is working well.
How do I get a similar behaviour with MXML?
I want to do the same thing, but omitting/including MXML tags in this way, not blocks of AS code.
My solution is to add some tags that could help to comment out unnecessary blocks of mxml code in certain build.
For example I want to add different buttons in Android and iOS builds:
<!-- iOS --><!--
<s:Button id="backBtn"
icon="{SHOW_LIST}"
click="navigator.popView()"/>
--><!-- /iOS -->
<!--Android-->
<s:Button id="exitBtn"
label="Exit"
click="NativeApplication.nativeApplication.exit()"/>
<!--/Android-->
Now run simple batch script which will comment out all Android specific code in the source for iOS build
PrepareForIos.cmd
#echo off
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--Android-->" "<!-- Android --><!--"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--/Android-->" "--><!-- /Android -->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!-- iOS --><!--" "<!--iOS-->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "--><!-- /iOS -->" "<!--/iOS-->"
pause
FART is a command-line tool for finding and replacing strings
Now our code looks like this and is ready to be built for iOS:
<!--iOS-->
<s:Button id="backBtn"
icon="{SHOW_LIST}"
click="navigator.popView()"/>
<!--/iOS-->
<!-- Android --><!--
<s:Button id="exitBtn"
label="Exit"
click="NativeApplication.nativeApplication.exit()"/>
--><!-- /Android -->
Inverse operation batch:
PrepareForAndroid.cmd
#echo off
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--Android-->" "<!-- Android --><!--"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--/Android-->" "--><!-- /Android -->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!-- iOS --><!--" "<!--iOS-->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "--><!-- /iOS -->" "<!--/iOS-->"
pause
A trick I use is to create a static class that holds constants for the different builds:
package
{
public class MyAppConstants
{
CONFIG::Debug
public static const DEBUG:Boolean = true;
CONFIG::Release
public static const DEBUG:Boolean = false;
}
}
And then I use these constants in my MXML:
<namespace:component visible="{MyAppConstants.DEBUG}" includeInLayout="{MyAppConstants.DEBUG}"/>
This will make sure the component is not added to the display list and thusly not measured either. If you would only use the visible attribute the dimensions of the component are still taken into account and will therefore leave "empty" spaces.
Edited response, based on this comment:
Sorry for being slow to get back to this thread. My intention was to have some interface elements (Buttons, and the like) which were omitted in some builds and included in others. My current workaround is to simply set the visible property of the component to the compiler defined boolean constant - it's crude, but it works. Any thoughts on a better way? – Chris Kitching Sep 20 at 14:40
I think you might be able to use the deferred initialisation behaviour of flex to control which components are created and added to your parent component - it might be a little against the idea of MXML, but I think it's possible.
Here is a bit of background on manually initialising deferred components (for spark and mx components):
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7aee.html
Flex 3
If you're using Flex 3 then you can override the createComponentsFromDescriptors() method and access the childDescriptors property to control exactly which child MXML components will be created.
The Creating deferred components article shows how you can get information about an MXML component from the descriptor. You could use this behaviour to determine which components should or shouldn't be instantiated for the current build.
Class reference for UIComponentDescriptor:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponentDescriptor.html
Flex 4
In Flex 4 it's a little less clear - all MXML components will be created from their descriptors (there isn't a childDescriptors property, just the mxmlContentFactory instance which will create all of the children).
Two options for controlling the display of MXML components might be:
Override the createDeferredContent() method and initialise the child components with the mxmlContentFactor but remove elements from the returned array before setting the mxmlContent property (which adds them to the display list).
Implement a template component that defines exactly what type of components are allowed as children, and only initialising the appropriate children for your current build type.
Here is an example of creating a template component in this way: Using IDeferredInstance in a template component.
Hopefully that gives you something to think about, and hopefully it's not too complicated :)
Original answer:
The short answer is that you can't use conditional compilation for MXML tags.
All MXML tags will be compiled into the component.
What are your goals in wanting to use conditional MXML?
Are you trying to include/exclude classes based on the compiler properties but still keep the short-hand MXML declarations? i.e. not have to define everything in actionscript.
With a bit more info we might be able to work through to an acceptable alternative :)

"Link" against a SWC in Flex

I'm trying to do a very simple app in Flash/Flex, that loads an image embedded in the swf itself and then shows it. The thing is I'm trying to do it using the command line only (mxmlc and compc) and without using #Embed, and failing miserably.
I have a very simple Main.as :
package
{
import flash.display.*;
import flash.utils.*;
public class Main extends Sprite
{
public function Main () : void
{
var pDef:Class = getDefinitionByName("icon_big.png") as Class;
var _image:BitmapData = new pDef(0, 0);
var pSprite:Sprite = new Sprite();
pSprite.graphics.beginBitmapFill(_image);
pSprite.graphics.drawRect(0, 0, _image.width, _image.height);
pSprite.graphics.endFill();
addChild(pSprite);
}
}
}
This works fine if I add icon_big.png to the Library using the Flash IDE, but I can't figure out how to do it from the command line.
I'm using compc to put the png inside a swc :
compc --include-file icon_big.png icon_big.png -output assets.swc
This generates a 17 kb assets.swf, slightly bigger than icon_big.png. Then I try to compile and link Main.as :
mxmlc -include-libraries+=assets.swc Main.as
This produces a 944 byte Main.swf, which clearly doesn't include the asset, and fails at runtime.
According to the mxmlc docs I found, -include-libraries should link with every class, including the ones not directly referenced by code (as is the case here, since I'm getting the class from code), and it unsurprisingly fails at runtime.
Note that this same code (or, more precisely, quite equivalent code) works when used within a Flash project - I'm not looking to fix the code, but how to do in the command line whatever Flash does internally.
I feel I'm just "not getting" something... any clues?
I recommend you to download the swftools from swftools.org. Once you have them, run:
swfdump -D assets.swf
Take a look in particular at the output which relates to SWF tag with value 76 (0x4C), called SYMBOLCLASS.
Here is an example of an exported class, named IntegerMemberBySlot:
[04c] 24 SYMBOLCLASS
exports 0001 as "IntegerMemberBySlot"
What symbols are you exporting from your assets.swf?
Have you tried adding the path of the assets to your source path parameter when compiling with mxmlc?
-source-path ./PATH/TO/ASSET
I think you need to embed the PNGs in a class, then compile that class into a SWC. I don't think you can put the PNGs directly into a SWC like you are trying to, but I could be wrong.
I had a similar situation (large project, resource swc with graphic assets), and no matter what I tried, I could't get Flex to include assets and classes not directly referenced from the project (I wanted to include different skins, and then instantiate the proper one at runtime, depending on the configuration).
Finally, I found a workaround by instead of static swc liking, switching over to runtime shared libraries (RSLs). Basically, flex unbundles the swc, and loads and links the included swf in runtime, before running the application itself. All of the classes and assets in the swf are loaded this way. May not be exactly what you're after, but it works for me.

Resources